]]>
]]>
Рейтинг@Mail.ru

XML парсер с кэшированием

Материал из Веб программирование.

Перейти к: навигация, поиск

Пример XML парсер с кешированием и созданием автоматической структуры XML на массиве.

  • потребуеться библиотека PEAR
  • и к нему Unserializer.php из модуля XML_Serializer, которому так же могут потребоваться XML_Util и XML_Parser

Алгоритм:

  • Если кеш устаревший или еще не был создан, береться XML файл по ссылке и сохраняеться на диске, Парсер парсит файл в структуру из массива, которую создает автоматически класс Unserializer, затем из массива тащим данные в базу.
  • Если кеш еще действителен, то не трогаем XML, и завершаем работу.

Таким образом получаеться база с данными из которой можно уже любым способом тащить данные.


Функция для кеширование XML страниц

Назовем xmlfunc.php и будем подключать в главном коде.

Функции передаются cacheFetch два параметра $url - ссылка прямая и $age - возраст когда устаревает кеш (в секундах).

При обращение к функции если кеш устаревший, обновляет кеш сохраняя XML файл на диске.

function cacheFetch($url,$age)
{
    // directory in which to store cached files, must be writable by PHP
    $cacheDir = $_SERVER["DOCUMENT_ROOT"].'/xml/cache/';
    $isupdated=0;
 
    // cache filename constructed from MD5 hash of URL
    $filename = $cacheDir.md5($url);
    // default to fetch the file
    $fetch = true;
    // but if the file exists, don't fetch if it is recent enough
    if (file_exists($filename))
    {
      $fetch = (filemtime($filename) < (time()-$age));
    }
 
    // fetch the file if required
    if ($fetch)
    {
    //echo 'update do';
    // обновляем кеш.
    if (!$handle = fopen($url, 'rb')) {
         //echo "Не могу открыть файл ($filename)";
         return false;
    }
    else
    {
      $somecontent = '';
      while (!feof($handle)) {
        $somecontent .= fread($handle, 8192);
      }
      fclose($handle);
    }
 
    if (!$handle = fopen($filename, 'w+')) {
         //echo "Не могу открыть файл ($filename)";
         return false;
    }
    if (fwrite($handle, $somecontent) === FALSE) {
        //echo "Не могу произвести запись в файл ($filename)";
        return false;
    } 
      fclose($handle);
      $isupdated=1;
    }
    // return the filename only if not return false
    return array('filename'=>$filename, 'isupdated'=>$isupdated);
}


Основной код:

Задача из XML файла перегнать структуру в массив и сохранить в базе. Делаем если только был обновлен кеш.

Получаем массив с помощью: $Unserializer->getUnserializedData();

Массив получается со стандартной структорой из которой можно сделать выборку по нужные нам полям.

По ходу дела комментарий...

//подключаем функцию кеш и класс для XML, библиотека Pear уже стоит на сервере
require_once $_SERVER["DOCUMENT_ROOT"].'/xml/xmlfunc.php';
require_once $_SERVER["DOCUMENT_ROOT"].'/xml/pear/Unserializer.php'; 
 
if ($yes) //заглушка
{
if ($cachedata = cacheFetch("http://www.webproger.ru/xml.xml,86400"))
{
//параметр $debug - если включить показывает системные сообщения как проходит наша работа
if ($debug)
{
echo "Cached XML file: {$cachedata['filename']}<br/><br/>";
}
if ($cachedata['isupdated'])  //функция cacheFetch возращяет был ли обновлен кеш файл
{
//настройки XML_Unserializer
$options = array(
                  XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE    => true,
                  XML_UNSERIALIZER_OPTION_FORCE_ENUM => Array('Hotel') //option: list of tags that will always be enumerated
                );
 
// Instantiate the serializer 
$Unserializer = &new XML_Unserializer($options); 
 
// Serialize the data structure 
$status = $Unserializer->unserialize($cachedata['filename'],true); 
 
// Check whether serialization worked 
if (PEAR::isError($status)) { 
   die($status->getMessage()); 
} 
 
// Display the PHP data structure
if ($debug)
{
echo "Parsing XML prices, array structure:<br/><br/>"; 
}
//сохраняем XML структуру в массив, дальше работаем только с массивом
$data=$Unserializer->getUnserializedData();
 
if ($debug)
{
echo '<pre>'; 
print_r($data); 
echo '</pre>'; 
 
echo "<br/>Parsing XML in Base:<br/><br/>";
}
 
//Prepare data GET ID Prices, Здесь уникальный номер ID 
foreach ($data as $k_level1=>$v_level1)
{
  if (is_array($v_level1))
  {
    //echo "$k_level1: {<br/>";
    foreach ($v_level1 as $k_level2=>$v_level2)
    {
      if (is_array($v_level2))
      {
        //echo "--$k_level2: {<br/>";
        foreach ($v_level2 as $k_level3=>$v_level3)
        {
          if (is_array($v_level3))
          {
            /*foreach ($v_level3 as $k_level4=>$v_level4)
            {
              $structure[$k_level4][]=$v_level43;
            }*/
          }
          else
          {     
            $structure[$k_level3][]=$v_level3;
            //echo "----$k_level3: $v_level3<br/>";
          }
         }
        //echo "  }<br/>";
        }
      else
      {
        //echo "$k_level2: $v_level2<br/>";
      }
    }
    //echo "}<br/>";
  }
}
 
if ($debug)
{
echo '<pre>'; 
print_r($structure); 
echo '</pre>';
}
 
if (sizeof($structure['id']))
{
    $structure['id']=array_flip($structure['id']);
 
    foreach ($structure['id'] as $k=>$v)
    {
      //echo "$k=>$v<br/>";
      $fieldsru = array(
      'HotelID' => $data['Hotel'][$v]['id'],
      'Lang' => 'ru',
      'Title' => addslashes($data['Hotel'][$v]['Title']),
      'Category' => addslashes($data['Hotel'][$v]['Category']['_content']),
      'CategoryID' => $data['Hotel'][$v]['Category']['id'],
      'Operator' => addslashes($data['Hotel'][$v]['Operator']['_content'])
    );
    $fieldslv = array(
      'HotelID' => $data['Hotel'][$v]['id'],
      'Lang' => 'lv',
      'Title' => addslashes($data['Hotel'][$v]['Title']),
      'Category' => addslashes($data['Hotel'][$v]['Category']['_content']),
      'CategoryID' => $data['Hotel'][$v]['Category']['id'],
      'Operator' => addslashes($data['Hotel'][$v]['Operator']['_content'])
 
    );
 
if ($debug)
{      			
      echo '<pre>';
      var_dump($fieldsru);	
      echo '<pre>'; 
 
      echo '<pre>';
      var_dump($fieldslv);	
      echo '<pre>'; 	
}      
   $res = $modx->db->select('HotelID', 'xml_hotels', 'HotelID="'.$data['Hotel'][$v]['id'].'"');
   if($modx->db->getRecordCount($res))
   {
      if ($fieldsru['Description'])
      $modx->db->update($fieldsru, 'xml_hotels', 'HotelID="'.$data['Hotel'][$v]['id'].'" and Lang="ru"');
      if ($fieldslv['Description'])
      $modx->db->update($fieldslv, 'xml_hotels', 'HotelID="'.$data['Hotel'][$v]['id'].'" and Lang="lv"');
 
      if ($debug)
      {
        echo 'Updated<br/>';
      }
   }
   else
   {
      if ($fieldsru['Description'])
      $modx->db->insert($fieldsru, 'xml_hotels');
      if ($fieldslv['Description'])
      $modx->db->insert($fieldslv, 'xml_hotels');
      if ($debug)
      {
        echo 'Inserted<br/>';   
      }
   }
}
}
else
{
  if ($debug)
  {
    echo "<br/>Is already cached!<br/><br/>";
  }
}
 
}
else
{
  if ($debug)
  {
    echo 'Temporarily unavailable, please try later.';
  }
}
}
}
else
{
  if ($debug)
  {
    echo "Wrong param!";
  }
}
]]>
Google+
]]>
Личные инструменты
Хочешь еще цитату? Никогда не забывайте — для претендующего на место под солнцем специалиста, кроме умения хорошо работать, очень важно уметь правильно преподнести себя, вкусно приправить и дорого продать.
веб-программирование
Просмотры
чтим

Deprecated: Function set_magic_quotes_runtime() is deprecated in /var/www/webproger/data/www/webproger.ru/1c6a72389c0fd92079ac7ae7cd356173/sape.php on line 218 Deprecated: Function set_magic_quotes_runtime() is deprecated in /var/www/webproger/data/www/webproger.ru/1c6a72389c0fd92079ac7ae7cd356173/sape.php on line 224

]]>
Rambler's Top100
]]>
]]>
]]>