Генератор карты сайта

leosun

Новичок
Генератор карты сайта

Выкладываю генератор карты сайта, очень хочется что бы те кому он нужен посмотрели его и сказали есть какие-то в нем баги или нет
PHP:
<?php
  // Библиотека для конвертирования страниц в CP1251
  require_once('libs/a.charset.php');

  // Настройки MySQL сервера
  require_once('mysql_connect.inc.php');

  // Время отработки скрипта - столько сколько нужно
  set_time_limit(0);
  ob_start();

  // Загрузить страницу по адресу
  function GetUrl($url){
  	// На всякий случай нужно удалить пробелы из URL
	$url = trim($url);

	// Инизиалируем библиотеку CURL
	$ch = curl_init();

	// Передаем адрес для загрузки
	curl_setopt($ch, CURLOPT_URL, $url);

	// Результат вернем в переменную
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

	// Если есть редирект - следуем по его адрему
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

	// Ожидание не более 15 секунд
	curl_setopt($ch, CURLOPT_TIMEOUT, 15);

	// Загружаем полученный ответ в пемеренную
	$content = curl_exec($ch);

	// Получаем заголовки ответа
	$info = curl_getinfo($ch);

	// Закрываем соединение с библиотекой CURL
	curl_close($ch);

	// Если ответ сервера не 404, то удаляем все теги кроме ссылок и
	// возвращаем результат
    if ($info['http_code'] != 404)
    return stripcslashes(strip_tags(charset_x_win($content),'<a>'));
  }

  // Задать адрес начальной страницы для построения карты сайта
  $start_url = 'http://www.migavia.ru/';

  // Получить отдельно домен и стартовую страницу сайта
  preg_match('@[url]http://[/url](.*)[/ ]@',$start_url,$abs_url);

  // Получить домен сайта
  $abs_url = 'http://'.$abs_url[1];

  // Очистить таблицу с картой сайта
  $sql = 'TRUNCATE TABLE `sitemap_tb`';
  mysql_query($sql);

  // Добавить стартовую страницу в базу данных
  $sql = "INSERT INTO `sitemap_tb` (`url`, `url_md5`, `checked`) VALUES ('$start_url', '".md5($start_url)."', '0')";
  mysql_query($sql);

  // Запустить генератор карты сайта
  CreateMap();

  // Генератор карты сайты
  function CreateMap(){
  	global $abs_url;
    // Выбрать еще не отработанные страницы
	$sql = 'SELECT * FROM `sitemap_tb` WHERE `checked` = 0';
  	$result = mysql_query($sql);
  	// Начать обрабатывать список страниц
  	while ($row = mysql_fetch_array($result)){
  	  // Текущий URL можно исключить из обработки
  	  $sql = "UPDATE `sitemap_tb` SET `checked` = 1 WHERE `url_md5` = '".md5($row['url'])."'";
  	  mysql_query($sql);
	  // Получить в переменную очередную обрабатываемую страницу
      $html_a = GetUrl($row['url']);
	  // Вырезаем все что есть в href из полученной страницы
   	  preg_match_all('@href=[\'"]([^\'"]+)[\'"]@si', $html_a, $list_a);
	  // Освободим немного памяти
   	  unset($list_a[0]);
   	  // Удалить лишнии ссылки и сделать из внутренних внешние
	  foreach ($list_a[1] as $key => $value_url){
		// Если ссылка - почтовый адрес или https или ftp, то его нужно удалить
		if (preg_match("@(mailto|#|https|ftp|.jpg|.png|.gif)@",$value_url)){
		  unset($list_a[1][$key]);
		} else {
		  // Если найденная ссылка внешняя, то нужно определить на какой url
		  // она ссылается
		  if (preg_match("@http@",$value_url)){
		    // Если ссылка ссылается на внешний ресурс то удалить ее
			if (!preg_match("@$abs_url@",$value_url))
			  unset($list_a[1][$key]);
		  } else {
		    // Если ссылка внетренняя то сделать ее внешней
		    if (preg_match('@(\.\./|\./)@',$value_url)){
			// Особый случай когда ссылка относительная
			$list_a[1][$key] = preg_replace("@/\?.*\.\.@", '', $row['url'].$value_url);
		    } else if ($value_url[0] != '/')
			$list_a[1][$key] = $abs_url.'/'.$value_url;
			else
			$list_a[1][$key] = $abs_url.$value_url;
		  }
		}
	  }
      // Найденные ссылки обработаны их можно добавить в базу
  	  foreach ($list_a[1] as $key => $value_url){
      	$sql = "INSERT INTO `sitemap_tb` (`url`, `url_md5`, `checked`) VALUES ('$value_url','".md5($value_url)."',0);";
      	// Добавить новый адрес, т.к. поле с md5 уникально - то повторов не будет
      	@mysql_query($sql);
  	  }
  	}
	// Если в базе осталось что-то
	$sql = 'SELECT * FROM `sitemap_tb` WHERE `checked` = 0';
  	$result = mysql_query($sql);
    echo 'Осталось обработать примерно - '.mysql_num_rows($result).'<br>';
    ob_flush();
    flush();
  	// Запустим прогон еще раз
  	if (mysql_num_rows($result) > 0) CreateMap();
  }
?>
CREATE TABLE `sitemap_tb` (
`id` int(11) NOT NULL auto_increment,
`url` varchar(255) NOT NULL,
`url_md5` varchar(32) NOT NULL,
`checked` varchar(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `url_md5_2` (`url_md5`),
KEY `url` (`url`),
KEY `checked` (`checked`)
) ENGINE=MyISAM AUTO_INCREMENT=166 DEFAULT CHARSET=cp1251 AUTO_INCREMENT=166 ;
 

x-yuri

Новичок
слишком много комментариев, за ними никакие баги не видны

-~{}~ 24.12.08 17:58:

// Освободим немного памяти
unset($list_a[0]);
улыбнуло, сколько памяти при этом освободилось?
 

leosun

Новичок
Автор оригинала: x-yuri
слишком много комментариев, за ними никакие баги не видны

-~{}~ 24.12.08 17:58:


улыбнуло, сколько памяти при этом освободилось?
Немного, но если ссылок на странице очень много, то прилично можно конечно было сделать так
$list_a = $list_a[1]; но лень было потом менять имя переменной в коде
 

x-yuri

Новичок
лучше без рекурсии - освобождать память не прийдется
 

leosun

Новичок
Не получиться без рекурсии - есть сайт на нем есть ссылки, по ссылкам есть еще ссылки, по которым есть еще ссылки, типичная рекурсия получается
 

x-yuri

Новичок
добавь отступы и подсветку синтаксиса
еще неплохо бы каждый запрос к бд в функцию запихнуть (усложняет чтение):
sitemap_clear()
sitemap_create( $url ) - возвращает id записи
sitemap_non_checked() - возвращает массив urlов
sitemap_mark_checked( $id )

-~{}~ 24.12.08 18:15:

Не получиться без рекурсии - есть сайт на нем есть ссылки, по ссылкам есть еще ссылки, по которым есть еще ссылки, типичная рекурсия получается
в скрипте рекурсию не обязательно использовать
PHP:
while( count(sitemap_non_checked()) ) {
    CreateMap();
}
или можно создать sitemap_non_checked_count()
 

leosun

Новичок
Да, насчет обхода без рекурсии действительно верно, спасибо!
 
Сверху