Помогите разбить карту сайта на части

Тема в разделе "PHP", создана пользователем DemonXT, 16 июл 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. DemonXT

    DemonXT Создатель

    Регистр.:
    15 июл 2009
    Сообщения:
    19
    Симпатии:
    0
    xml карта моего сайта разраслась на столько, что google её уже не принимает!
    Помогите разбить его на части, но чтобы не нарушилась структура xml-файла.
    Нашёл и немного модифицировал скрипт, который просто делит файл на части:
    PHP:
    <?PHP
    // Имя файла
    $filename "sitemap.xml";
    // Разбиваем файл на куски по 4,5 Мб.
    // За одно и запишем их в разные файлы
    $piece 4718592;
    // Открываем исходный файл
    $fp fopen($filename"r");
    // Читаем содержимое файла в буфер
    $bufer fread($fpfilesize($filename));
    // Закрываем файл
    fclose($fp);
    // Подсчитываем число кусков, на которые
    // разобьётся файл
    $count = (int)filesize($filename)/$piece;
    if((float)(
    filesize($filename)/$piece) - $count != 0$count++;
    // В цикле разбиваем содержимое файла в переменной
    // $bufer на части
    for($i=0$i<$count; ++$i)
    {
        
    $part substr($bufer,$i*$piece,$piece);
        
    $fname "sitemap".$i;
        
    $fname $fname.".xml";
        
    // Сохраняем кусок в файле
        
    $fp fopen($fname,"w");
        
    fwrite($fp,$part);
        
    fclose($fp);
    }
    ?>
    Но он просто делит файл на части равные заданное количество байт.
    Файл sitemap.xml имеет вид:
    Код:
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    	<url>
    		<loc>http://site.ru/google.html</loc>
    		<lastmod>2010-07-15</lastmod>
    		<priority>0.5</priority>
    	</url>
    	<url>
    		<loc>http://site.ru/reklama.html</loc>
    		<lastmod>2010-07-15</lastmod>
    		<priority>0.5</priority>
    	</url>
    	<url>
    		<loc>http://site.ru/rules_news.html</loc>
    		<lastmod>2010-07-15</lastmod>
    		<priority>0.5</priority>
    	</url>
    ...
    	<url>
    		<loc>http://site.ru/soft/</loc>
    		<lastmod>2010-07-15</lastmod>
    		<priority>0.7</priority>
    	</url>
    </urlset>
    
    То есть в первой части нужно откусить по строку: " </url>" и в конец вставить строку: "</urlset>", а в начало следующего вставить шапку:
    Код:
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    Очень нужна Ваша помощь. Заранее спасибо.:thenks:
     
  2. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    PHP:
    <?php
    $x_limit 
    2518592// нужный размер в байтах (символ ASCII - 1 байт)
    set_time_limit(0); $t_start microtime(1);
    $xml_file=file('sitemap.xml');
    function 
    xml_filter($str) { if(preg_match('/^(<\?xml|<urlset|<\/urlset>)/i',$str)) return 0; else return 1; }
    $xml_file=array_filter($xml_file,'xml_filter');
    $str_xml=join('',$xml_file);

    preg_match_all("/<url>.{1,10000}<\/url>/is"$str_xml$x_res);
    $x_join $x_limit/10000// укрупнение массива
    foreach ($x_res[0] as $value): $i++; $value1 .= $value;
    if(!(
    $i%$x_join)) { $x_arr[]=$value1; unset($value1); }
    endforeach; 
    $x_arr[]=$value1; unset($x_res);

    // header и footer
    $x_s='<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
    ;
    $x_e='</urlset>';

    // форматирование и запись
    $i=1; foreach ($x_arr as $value): $value $x_s."\n".$value."\n".$x_e;
    file_put_contents('sitemap'.$i++.'.xml',$value); endforeach;
    if(
    $value) echo 'file split - ok - used time -'.round((microtime(1)-$t_start),4).' sec';
    ?>
     
    DemonXT нравится это.
  3. DemonXT

    DemonXT Создатель

    Регистр.:
    15 июл 2009
    Сообщения:
    19
    Симпатии:
    0
    Большое СПАСИБО!

    Даже не ожидал получить так скоро ответ. :yahoo:
    Но, возникла проблема при выполнении скрипта. Связанная с нехваткой памяти.
    Вот ошибка, которую выдаёт сервер:
    Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 35 bytes) in /uploads/splitfix.php on line 4
     
  4. diavolic

    diavolic

    Регистр.:
    17 мар 2010
    Сообщения:
    522
    Симпатии:
    102
    поправь в php.ini

    memory_limit = 128M
     
  5. komyak

    komyak

    Регистр.:
    4 фев 2009
    Сообщения:
    482
    Симпатии:
    183
    Попробуй в .htaccess добавить эту строку:
    Код:
    php_value memory_limit 64M
    
    Ну и карта, на 33 метра...
     
  6. DemonXT

    DemonXT Создатель

    Регистр.:
    15 июл 2009
    Сообщения:
    19
    Симпатии:
    0
    Я нахожусь на виртуальном хостинге. Доступа к файлу php.ini у меня нет.
    Попробую попросить хостера.
     
  7. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    оптимизированная версия, исп. в 2-3 раза меньше памяти т.к. убран массив из sitemap, удаляются неиспользуемые переменные
    при xml размером 7 Mb, скрипт требует 21 Mb оп. памяти

    PHP:
    <?php
    $x_limit 
    2518592// нужный размер в байтах (символ ASCII - 1 байт)
    set_time_limit(90); $t_start microtime(1);
    $str_xml=file_get_contents('sitemap.xml');
    $x_r=array('/<\?xml[^>]*?\?>/i','/<urlset[^>]*?>/i','/<\/urlset>/i');
    $str_xml=preg_replace($x_r,'',stristr($str_xml,'<url>')); // удаляем header и footer

    preg_match_all("/<url>.{1,10000}<\/url>/is"$str_xml$x_res);
    echo 
    'max used memory '.number_format((memory_get_usage()-$m_start)/(1024*1024))." Mb<br />\n"$str_xml=NULL;
    $x_join $x_limit/10000// укрупнение массива
    foreach ($x_res[0] as $value): $i++; $value1 .= $value;
    if(!(
    $i%$x_join)) { $x_arr[]=$value1; unset($value1); }
    endforeach; 
    $x_arr[]=$value1;
    $x_res=NULL;
    // header и footer
    $x_s='<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
    ;
    $x_e='</urlset>';
    // форматирование и запись
    $i=1; foreach ($x_arr as $value): $value $x_s."\n".$value."\n".$x_e;
    file_put_contents('sitemap'.$i++.'.xml',$value); endforeach;
    if(
    $value) echo 'file split - ok - used time - '.round((microtime(1)-$t_start),4).' sec';
    ?>
     
    DemonXT нравится это.
  8. DemonXT

    DemonXT Создатель

    Регистр.:
    15 июл 2009
    Сообщения:
    19
    Симпатии:
    0
    Удалось увеличить лимит памяти и php.ini. Скрипт отрабатывал, но всё равно выскакивала ошибка о нехватка памяти!
    Второй вариант просто великолепен. Отрабатывает без единой ошибки!
    pitkina :ay:
     
Статус темы:
Закрыта.