Загрузка прайса из XML в PHP +автоматический импорт изображений!

Недавно появилась необходимость написания импорта прайс-листа из одного интернет-магазина в другой.

Приводить код для поиска и обновления базы данных я не буду — это уже совсем просто, а вот код, который отвечает за импорт данных из XML и автоматическую загрузку изображений — это пожалуйста.

И так, задаём структуру XML-документа:


<?xml version="1.0" encoding="UTF-8"?>
 <sponsor>
 <rows cnt="20">
 <row id="1">
 <id_goods>1</id_goods>
 <place>Мобильный телефон</place>
 <url>http://kit.kiev.ua/im_sh/013R00625.jpg</url>
 <price>0.4</price>
 <shop>Есть</shop>
 </row>

 <row id="2">
 <id_goods>2</id_goods>
 <place>Мобильный телефон 2</place>
 <url>http://kit.kiev.ua/im_sh/0917B002.jpg</url>
 <price>122.22</price>
 <shop>Есть</shop>
 </row>

 <row id="3">
 <id_goods>3</id_goods>
 <place>Мобильный телефон 3</place>
 <url>http://kit.kiev.ua/im_sh/Q7516A.jpg</url>
 <price>905</price>
 <shop>Под заказ</shop>
 </row>

 </rows>
 </sponsor>

Сразу обращаю внимание на кодировку документа. Очень часто кодировку нужно будет конвертировать средствами PHP.

И так, допустим мы закачали файл на сервер. Прочитали его.

В примере я сразу указываю XML-документ:


<?php
class GetImage {

var $source;
var $save_to;
var $set_extension;
var $quality;

function download($method = 'curl')
{
$info = @GetImageSize($this->source);
$mime = $info['mime'];

if(!$mime) exit('Не могу определить тип');

$type = substr(strrchr($mime, '/'), 1);

switch ($type)
{
case 'jpeg':
 $image_create_func = 'ImageCreateFromJPEG';
 $image_save_func = 'ImageJPEG';
 $new_image_ext = 'jpg';

 $quality = isSet($this->quality) ? $this->quality : 100;
 break;

case 'png':
 $image_create_func = 'ImageCreateFromPNG';
 $image_save_func = 'ImagePNG';
 $new_image_ext = 'png';

 $quality = isSet($this->quality) ? $this->quality : 0;
 break;

case 'bmp':
 $image_create_func = 'ImageCreateFromBMP';
 $image_save_func = 'ImageBMP';
 $new_image_ext = 'bmp';
 break;

case 'gif':
 $image_create_func = 'ImageCreateFromGIF';
 $image_save_func = 'ImageGIF';
 $new_image_ext = 'gif';
 break;

case 'vnd.wap.wbmp':
 $image_create_func = 'ImageCreateFromWBMP';
 $image_save_func = 'ImageWBMP';
 $new_image_ext = 'bmp';
 break;

case 'xbm':
 $image_create_func = 'ImageCreateFromXBM';
 $image_save_func = 'ImageXBM';
 $new_image_ext = 'xbm';
 break;

default:
 $image_create_func = 'ImageCreateFromJPEG';
 $image_save_func = 'ImageJPEG';
 $new_image_ext = 'jpg';
}

if(isSet($this->set_extension))
{
$ext = strrchr($this->source, ".");
$strlen = strlen($ext);
$new_name = basename(substr($this->source, 0, -$strlen)).'.'.$new_image_ext;
}
else
{
$new_name = basename($this->source);
}

$save_to = $this->save_to.$new_name;

 if($method == 'curl')
 {
 $save_image = $this->LoadImageCURL($save_to);
 }
 elseif($method == 'gd')
 {
 $img = $image_create_func($this->source);

 if(isSet($quality))
 {
 $save_image = $image_save_func($img, $save_to, $quality);
 }
 else
 {
 $save_image = $image_save_func($img, $save_to);
 }
 }

 return $save_image;
}

function LoadImageCURL($save_to)
{
$ch = curl_init($this->source);
$fp = fopen($save_to, "wb");

$options = array(CURLOPT_FILE => $fp,
 CURLOPT_HEADER => 0,
 CURLOPT_FOLLOWLOCATION => 1,
 CURLOPT_TIMEOUT => 60);

curl_setopt_array($ch, $options);

$save = curl_exec($ch);
curl_close($ch);
fclose($fp);

return $save;
}
}

$importStr ='<?xml version="1.0" encoding="UTF-8"?>
 <sponsor>
 <rows cnt="20">
 <row id="1">
 <id_goods>1</id_goods>
 <place>Мобильный телефон</place>
 <url>http://kit.kiev.ua/im_sh/013R00625.jpg</url>
 <price>0.4</price>
 <shop>Есть</shop>
 </row>

 <row id="2">
 <id_goods>2</id_goods>
 <place>Мобильный телефон 2</place>
 <url>http://kit.kiev.ua/im_sh/0917B002.jpg</url>
 <price>122.22</price>
 <shop>Есть</shop>
 </row>

 <row id="3">
 <id_goods>3</id_goods>
 <place>Мобильный телефон 3</place>
 <url>http://kit.kiev.ua/im_sh/Q7516A.jpg</url>
 <price>905</price>
 <shop>Под заказ</shop>
 </row>

 </rows>
 </sponsor>
 ';

 $xml = simplexml_load_string($importStr);
 /*echo '<pre>';
 var_dump($xml);
 echo '</pre>';*/

 echo '<table border="1">';
 foreach ( $xml->rows->row as $row )
 {
 echo '<tr>';
 echo '<td>'.$row->id_goods.'</td><td>'.$row->place.'</td>';
 echo '<td>'.$row->url.'</td><td>'.$row->price.'</td>';
 echo '<td>'.$row->shop.'</td>';
 echo '</tr>';
 /* Закачиваем изображение *//*
$a=0;
$timevalue = time();
$photoname = $timevalue.$a.'.jpg';
$ch = curl_init($row->url);
echo $row->url;
$fp = fopen($photoname, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);

curl_setopt($ch, CURLOPT_VERBOSE, 0);

curl_exec($ch);
curl_close($ch);
fclose($fp);*/

$image = new GetImage;

$image->source = $row->url;
$image->save_to = './img';

$get = $image->download('curl');
 }
 echo '</table>';
?>

Теперь по частям:


$xml = simplexml_load_string($importStr);

Конвертируем данные XML в массив. Кому интересно что получаем, может воспользоваться кодом, который под комментарием:


echo '<pre>';
 var_dump($xml);
 echo '</pre>';

Дальше выводим на экран в виде таблице полученные данные:


echo '<table border="1">';
 foreach ( $xml->rows->row as $row )
 {
 echo '<tr>';
 echo '<td>'.$row->id_goods.'</td><td>'.$row->place.'</td>';
 echo '<td>'.$row->url.'</td><td>'.$row->price.'</td>';
 echo '<td>'.$row->shop.'</td>';
 echo '</tr>';

}

echo '</table>';

Если данные нужно загружать в базу, тогда убираем вывод таблицы и создаем SQL (или другие) запросы для добавления в базу.

Теперь задача — закачать изображения с чужого сайта на свой.

Читатель наверняка заметил закомментированный код в цикле:


$timevalue = time();
$photoname = $timevalue.$a.'.jpg';
$ch = curl_init($row->url);
echo $row->url;
$fp = fopen($photoname, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);

curl_setopt($ch, CURLOPT_VERBOSE, 0);

curl_exec($ch);
curl_close($ch);
fclose($fp);

А закомментирован он потому, что некоторые изображения не успевали загрузиться. По этому пришлось использовать класс, который значительно расширяет функционал загрузки.

И так, создаем объект класса и скачиваем файл:


$image = new GetImage;

$image->source = $row->url;
$image->save_to = 'img/';

$get = $image->download('curl');

Этот код должен быть внутри цикла, который работает с данными XML.

Вот и всё!  Основная задача решена. Теперь можно применять к загруженному файлу масштабирование, кропы и т.д.

Скачать исходники

Создаем карту сайта и прочее :)

В это посте, я хочу познакомить вас с замечательным сервисом, который создает:
un-compressed XML Sitemap
compressed XML Sitemap
ROR Sitemap
HTML Sitemap
Sitemap in Text Format

Вот сам сервис. До 500 страниц — создает бесплатно!

Для чего нужна карта сайта (sitemap)?

Как можно заметить, сейчас почти все сайты имеют либо картинку с изображением дерева либо в файле robots.txt можно заметить такую строку:

1
Sitemap: http://vazelin.org.ua/sitemap.xml

Sitemap или на русском, карта сайта, служит для удобства индексации поисковых систем и для пользователей. С помощью данной карты можно легко перейти в нужную категорию или рубрику. Т.к. данный файл занимает мало места, то он очень удобен для владельцев PDA устройств и для тех, у кого небольшой запас трафика.

Sitemap.xml представляет собой структуризированный xml документ с заголовками полей по стандарту sitemap для поисковых систем.
Рассмотрим структуру этого файлика:

1
2
3
4
5
6
<url>
<loc>http://vazelin.org.ua/</loc>
        <lastmod>2009-09-21T10:57:34+00:00</lastmod>
        <changefreq>always</changefreq>
        <priority>1.0</priority>
    </url>

url — создаем блок и даем роботу понять, что это новая ссылка;
loc — location, ссылка на одну из страничек вашего сайта;
lastmod — когда была изменена страница;
changefreq — частота, с которой обновляется эта страница (always -всегда, hourly — каждый час, daily — ежедневно, weekly — еженедельно, monthly — ежемесячно, yearly — ежегодно, never — никогда)
priority — приоритет для сканирования поисковым роботом, от 0.0 до 1.0.
Приоритетом и частотой обновления не стоит злоупотреблять.