Разработчику. Сборник рецептов PHP
Задавайте вопросы

Программа: Обнаружение свежих ссылок

Вернуться назад

Пример 11.6, fresh-links.php, – это модификация программы из рецепта (Программа: обнаружение устаревших сылок), которая выдает список ссылок и время их последнего изменения. Если сервер, на котором находится ссылка, не сообщает время последнего изменения, то в качестве времени последнего изменения программа возвращает время запроса URL.

Если запрос программой URL заканчивается неудачей, то она выводит код статуса, который программа получила при попытке получения содержимого URL. Запустите программу, передав ей URL для просмотра ссылок:

% fresh-links.php http://www.oreilly.com

http://www.oreilly.com/index.html: Fri Aug 16 16:48:34 2002
http://www.oreillynet.com: Mon Aug 19 10:18:54 2002
http://conferences.oreilly.com: Fri Aug 16 19:41:46 2002
http://international.oreilly.com: Fri Mar 29 18:06:32 2002
http://safari.oreilly.com: 302
http://www.oreilly.com/catalog/search.html: Tue Apr 2 19:05:57 2002
http://www.oreilly.com/oreilly/press/: 302
...

Этот вывод является результатом запуска программы примерно в 10:20 A.M. EDT 19 августа 2002 года. Ссылка на http://www.oreillynet.com очень свежая, а другие имеют различный возраст. За ссылкой на http://www.oreilly.com/oreilly/press/ нет времени последней модификации; вместо него стоит код статуса (302). Это означает, что ссылка была перемещена, как говорит нам результат работы stale-links.php в рецепте (Программа: обнаружение устаревших сылок)

Программа обнаружения свежих ссылок концептуально почти идентична программе поиска устаревших ссылок. Она использует ту же самую функцию pc_link_extractor() из рецепта (Преобразование ASCII в HTML); однако получение содержимого URL в программе реализовано на основе класса HTTP_Request вместо расширения c URL. Код для извлечения базового URL, указанного в командной строке, находится внутри цикла, так что он может следовать любой возвращенной переадресации.

Получив страницу, программа вызывает функцию pc_link_extractor(), чтобы сгенерировать список ссылок, имеющихся на странице. Затем, после присоединения базового URL в начало каждой ссылки, если это необходимо, для каждой ссылки, найденной на исходной странице, вызывается функция sendRequest(). Нам нужны лишь заголовки этих ответов, поэтому мы используем метод HEAD вместо метода GET. Однако вместо новых мест расположения перемещенных ссылок программа печатает отформатированную версию заголовка Last-Modified, если он доступен.

Пример 11.6. fresh-links.php

require 'HTTP/Request.php';

function pc_link_extractor($s) {
       $a = array();
       if (preg_match_all(
                     '/<A\s+.*?HREF=[\"\']?([^\"\' >]*)[\"\']?[^>]*>(.*?)<\/A>/i',
                     $s,$matches,PREG_SET_ORDER)) {
       foreach($matches as $match) {
              array_push($a,array($match[1],$match[2]));
       }
    }
    return $a;
}
$url = $_SERVER['argv'][1];

// извлекаем URL в цикле, чтобы следовать переадресациям
$done = 0;
while (! $done) {
              $req = new HTTP_Request($url);
              $req->sendRequest();
              if ($response_code = $req->getResponseCode()) {
                     if ((intval($response_code/100) == 3) &&
                            ($location = $req->getResponseHeader('Location'))) {
                            $url = $location;
              } else {
                            $done = 1;
              }
              } else {
                     return false;
              }
}

// определяем базовый url из url
// при этом не обращаем внимания на тег <base> на этой странице
$base_url = preg_replace('{^(.*/)([^/]*)$}','\\1',$req->_url->getURL());

// запоминаем ссылки, которые мы посетили, чтобы не посещать
// их более одного раза
$seen_links = array();

if ($body = $req->getResponseBody()) {
       $links = pc_link_extractor($body);
       foreach ($links as $link) {
              // пропускаем https URL
              if (preg_match('{^https://}',$link[0])) {
                     continue;
              }
// вычисляем относительные ссылки
if (! (preg_match('{^(http|mailto):}',$link[0]))) {
              $link[0] = $base_url.$link[0];
}
// пропускаем данную ссылку, если мы ее уже видели
if ($seen_links[$link[0]]) {
continue;
}

// отмечаем данную ссылку как просмотренную
$seen_links[$link[0]] = true;

// выводим содержимое ссылки, на которой находимся
print $link[0].': ';
flush();

// посещаем ссылку
$req2 = new HTTP_Request($link[0],
                     array('method' => HTTP_REQUEST_METHOD_HEAD));
$now = time();
$req2->sendRequest();
$response_code = $req2->getResponseCode();

// если получение содержимого закончилось успешно
if ($response_code == 200) {
              // получаем заголовок Last-Modified
              if ($lm = $req2->getResponseHeader('Last-Modified')) {
                     $lm_utc = strtotime($lm);
              } else {
                     // или устанавливаем Last-Modified в текущее время
                     $lm_utc = $now;
              }
              print strftime('%c',$lm_utc);
} else {
              // в противном случае, выводим код ответа
              print $response_code;
}
print "\n";
}
}

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования

Рейтинг Сайтов ДОСКИ.РУ