]]>
ваш баннер
]]>

PHP скрипт. Simple URL checker - выполнение проверок (cURL)

1 мая, 2008

Simple URL checker - cURL
Приветствую всех!

Как я и обещал, мы продолжаем разработку приложения для проверки URL и сегодня займемся непосредственно выполнением проверок.

Чтобы немного облегчить себе жизнь, проверки мы будем выполнять с помощью библиотеки cURL.

Эта библиотека предоставляет очень широкие возможности для работы с web ресурсами. Поддерживаются редиректы, отправка данных, установка заголовков, автоматически собирается статистика и многое другое. Естественно, все возможности гибко настраиваются. В общем, при желании можно полностью имитировать работу человека в интернете.

Теперь нам нужно подключить эту библиотеку к PHP. Для этого в файле php.ini нужно убрать «;» в начале строки extension=php_curl.dll. После этого в сведениях, которые возвращает функция phpinfo() появится раздел curl и в нем параметр - cURL support: enabled.

Библиотека подключена и можно начинать ее использовать.

Для начала приведу небольшой пример, иллюстрирующий основные принципы работы с библиотекой на PHP.

Code (php)
  1. $ch = curl_init();    // инициализация
  2. curl_setopt($ch, CURLOPT_URL, ‘http://www.google.com’); // устанавливаем URL
  3. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// разрешаем редирект
  4. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // указывает, что функция curl_exec должна вернуть полученный ответ, а не отправить его сразу браузеру
  5. $result = curl_exec($ch); // запуск
  6. curl_close($ch);
  7. echo $result;

Здесь все достаточно просто. Функция curl_init инициализирует библиотеку и создает объект для работы с ней ($ch). После этого с помощью функции curl_setopt можно настроить библиотеку. В первом параметре этой функции передаем созданный объект, во втором – указываем имя параметра, который нужно настроить, а в третьем – значение параметра.

После этого вызываем функцию curl_exec, которая и выполняет всю работу, т.е. отправляет запрос и получает данные.

Возвращаемся к нашему приложению.

Как я и говорил в прошлый раз, всю работу по проверке URL выполняет метод ping. Рассмотрим его подробнее.

Code (php)
  1. function ping($urlId = 0) {
  2.     $this->load->model(‘urlmodel’);
  3.     $this->load->model(‘resultmodel’);
  4.     $urls = array();
  5.     if ($urlId == 0) {
  6.         //получаем полный список URL из БД
  7.         $urls = $this->urlmodel->getAllUrls();
  8.     }
  9.     else {
  10.         //ищем выбранный URL
  11.         $urls = $this->urlmodel->getUrlById($urlId);
  12.     }
  13.     if ($urls !== FALSE) {
  14.         //создаем обработчик для параллельной работы с URL’ами
  15.         $mh = curl_multi_init();
  16.         //создаем обработчики для каждого отдельного URL и добавляем их в $mh
  17.         $handles = array();
  18.         for ($i = 0; $i < count($urls); $i++) {
  19.             $handles[$i] = curl_init();
  20.             curl_setopt($handles[$i], CURLOPT_URL, $urls[$i][‘URL’]);
  21.             curl_setopt($handles[$i], CURLOPT_RETURNTRANSFER, 1);
  22.             curl_setopt($handles[$i], CURLOPT_FOLLOWLOCATION, 1);
  23.             curl_setopt($handles[$i], CURLOPT_TIMEOUT, 10);
  24.             curl_setopt($handles[$i], CURLOPT_HEADER, 0);
  25.             //если используется прокси, нужно указать его порт и ip
  26.             //curl_setopt($handles[$i], CURLOPT_PROXYPORT, "8080");
  27.             //curl_setopt($handles[$i], CURLOPT_PROXY, "192.168.0.1");
  28.  
  29.             curl_multi_add_handle($mh, $handles[$i]);
  30.         }
  31.         //запускаем обработку
  32.         $running = null;
  33.         do {
  34.             curl_multi_exec($mh, $running);
  35.         } while ($running > 0);
  36.         //получаем данные и сохраняем их в БД
  37.         for ($i = 0; $i < count($urls); $i++) {
  38.             $urlInfo = curl_getinfo($handles[$i]);
  39.             $resData[‘urlId’] = $urls[$i][‘id’];
  40.             if ($urlInfo[’speed_download’] != 0) {
  41.                 $resData[‘result’] = 1;
  42.             }
  43.             else {
  44.                 $resData[‘result’] = 0;
  45.             }
  46.             $resData[‘responsetime’] = $urlInfo[‘total_time’];
  47.             $resData[‘responselength’] = $urlInfo[’size_download’];
  48.             $resData[‘responsespeed’] = $urlInfo[’speed_download’];
  49.             $this->resultmodel->saveResults($resData);
  50.         }
  51.         //закрываем обработчики
  52.         for ($i = 0; $i < count($handles); $i++) {
  53.             curl_multi_remove_handle($mh, $handles[$i]);
  54.         }
  55.         if ($urlId == 0) {
  56.             $this->index();
  57.         }
  58.         else {
  59.             $this->urldetails($urlId);
  60.         }
  61.     }
  62. }

Как видите, метод довольно объемный и достаточно сильно отличается от первого примера. Но обо всем по порядку.

После загрузки моделей, мы проверяем значение параметра $urlId. Если он равен нулю, то выполняем проверку всех URL в базе данных, если нет – проверяем только заданный URL.

Теперь нам нужно проверить найденные в базе данных URL. Если этот URL один, то все довольно просто, можно ограничиться кодом из первого примера, но у нас может быть несколько десятков URL. Запустить проверки в цикле, конечно, возможно, но это скрипт при этом может выполняться довольно долго. А в большинстве случаев время работы скриптов ограничено (параметр max_execution_time).

Поэтому здесь мы используем функцию curl_multi_init() (строка 15) для параллельной обработки нескольких запросов. По-сути, объект, который создает curl_multi_init, является контейнером для обычных обработчиков.

После этого в цикле (строки 18-30) с помощью curl_init мы создаем массив объектов для работы с каждым URL, настраиваем его и с помощью функции curl_multi_add_handle добавляем в контейнер (строка 29).

Обратите внимание на параметр CURLOPT_TIMEOUT (строка 23). Я установил его равным 10 секундам. Это время в течении которого cURL будет ждать ответ сервера. Значение я взял «с потолка», поэтому если оно вас не устраивает, можете спокойно его изменить.

Сейчас все готово для начала проверок. Запуск выполняется функцией curl_multi_exec, которая принимает два параметра. Первый – созданный объект с обработчиками, второй – переменная, указывающая завершилась обработка или нет.

Функция curl_multi_exec вызывается внутри цикла, выход из которого выполняется, когда переменная $running будет равна нулю, т.е. завершится обработка всех URL.

После этого нам остается только получить данные о проверках с помощью функции curl_getinfo (строка 38) и сформировать массив с результатами ($resData).

На завершающем этапе мы сохраняем данные в БД (строка 49), с помощью функции curl_multi_remove_handle закрываем обработчики (строка 53) и показываем посетителю страницу, с которой был вызван метод (строки 55-60).

Все. Метод для выполнения проверок готов. В следующий раз мы рассмотрим создание представлений, т.е. страниц сайта.

До встречи!

P.S. Ссылки на все статьи и примеры цикла я публикую здесь.

Понравилась статья? Подпишитесь на продолжение rss link !

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в PHP, Web разработка

]]>

Комментарии (5)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

  1. Henly 03.05.2008 в 17:18 (Ответить)

    Вы не учли что если включить прокси то $urlInfo[’speed_download’] будет не равен нулю даже если сайт не доступен!

  2. Henly 03.05.2008 в 17:37 (Ответить)

    попробовал подключиться через протокол https результат:
    $urlInfo[‘total_time’]=какая то цифра
    $urlInfo[’size_download’]= 0
    Сайт не доступен..
    хотя на самом деле сайт прекрасно работает.
    пробовал увеличить timeout непомогло. А курл хоть умеет с https работать?

  3. Владимир 03.05.2008 в 20:41 (Ответить)

    >> если включить прокси то $urlInfo[’speed_download’] будет не равен нулю

    Дело в том, что я тестировал подключение через прокси. И получил такой результат:
    Время отклика - 9.313
    Размер - 0
    Скорость - 0
    Использовал - CCProxy.
    Может быть для других прокси результат изменится?
    Если да, напишите, пожалуйста, с каким сервером вы проверяли.

    >> https
    Да, cURL его поддерживает. И проблемы с ним, насколько я знаю, довольно распространенные.
    Попробуйте использовать опцию

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    отключает поддержку сертификатов.

  4. Руслан 19.05.2008 в 14:33 (Ответить)

    Не работает:
    $ch = curl_init(); // инициализация
    curl_setopt($ch, CURLOPT_URL, ‘http://www.google.com’); // устанавливаем URL
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// разрешаем редирект
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // указывает, что функция curl_exec должна вернуть полученный ответ, а не отправить его сразу браузеру
    $result = curl_exec($ch); // запуск
    curl_close($ch);
    echo $result;

    $result = curl_exec($ch); не возвращяет ничего!!!
    Сайт на holm.ru
    Почему?

    1. Владимир 19.05.2008 в 15:59 (Ответить)

      Попробуйте запустить само приложение.
      Убедитесь, что подключен сURL (с помощью phpinfo()).
      Если вы скопировали код с этой страницы, убедитесь, что исправили кавычки во второй строке (их автоматически меняет wordpress).
      Попробуйте использовать параметр
      curl_setopt($ch, CURLOPT_VERBOSE, 1);

Оставить комментарий

Введите ваш комментарий

* - обязательные для заполнения поля

Quicktags:

]]>