Недавно появилась необходимость написания импорта прайс-листа из одного интернет-магазина в другой.
Приводить код для поиска и обновления базы данных я не буду — это уже совсем просто, а вот код, который отвечает за импорт данных из 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.
Вот и всё! Основная задача решена. Теперь можно применять к загруженному файлу масштабирование, кропы и т.д.
