php класс для работы с http через curl

11.11.2010

Начну писать снова помаленьку. А то совсем обленился. Вот решил поделится одной библиотечкой с которой работаю уже несколько лет. За это время она регулярно обновлялась, исправлялись старые баги добавлялись новые… По идеи это класс (между прочим первый класс который я написал на php) надстройка над curl, исключительно для облегчения работы и сохранения нервов.

И так, ссылка на репозиторий – httpclass там всегда можно будет найти свежую версию.
Дальше примеры.

Простое получение страницы

  1. <?php
  2.  
  3. require './http.php';
  4.  
  5. $http = new http;
  6. $page = $http->get('http://yandex.ru');
  7.  
  8. echo $page;
  9.  
  10. ?>

Отправка данных методом POST

  1. <?php
  2.  
  3. require './http.php';
  4.  
  5. $http = new http;
  6. $postdata = array(
  7.     'login' => 'root',
  8.     'passwd' => 'query',
  9. );
  10. $page = $http->post('http://yandex.ru', $postdata);
  11.  
  12. echo $page;
  13.  
  14. ?>

В последнем аргументе методов post и get можно указать кодировку в которой надо вернуть страницу

  1. <?php
  2.  
  3. require './http.php';
  4.  
  5. $http = new http;
  6. $page = $http->get('http://mail.ru/', 'utf-8');
  7.  
  8. // Исходная кодировка полученной страницы
  9. echo $http->encoding;
  10. echo $page;
  11.  
  12. ?>

Ну и наверное самое полезное – преобразование относительных адресов в абсолютные.

  1. <?php
  2.  
  3. require './http.php';
  4.  
  5. $action = http::fixUrl('http://example.com/dir/subdir/', '../action.php');
  6. echo $action; // http://example.com/dir/action.php
  7.  
  8. ?>

Для этого метода мне даже пришлось писать специальный тесты, их можно посмотреть тут. На сегодняшний день я не видел правильно работающую php функцию для этой задачи.

  1. # Сандер:

    Дельно :)
    А то каждый раз через этот curl задалбываешься правильно все выписывать.
    Возвращается, надо понимать, строка с текстом страницы? А еще, мне кажется, было бы очень полезно отдельную функцию, возвращающую все заголовки. Из этого вообще можно было бы мини веб-сервис сделать.

    P.S. Хорошо бы подписку на комментарии

  2. # Jeck:

    Сандер, добавил метод getHeaders.
    Пример:

    1. <?php
    2.  
    3. require './http.php';
    4.  
    5. $http = new http;
    6. $http->get('http://yandex.ru');
    7. echo '<pre>';
    8. echo $http->getHeaders();
    9. echo '</pre>';
    10.  
    11. ?>

    По поводу подписки, попробую, я в этом WP вообще не разбираюсь :( даже где эти дурацкие смайлы отключить не знаю…

    И да веб сервисов то полно вот например – http://pr-cy.ru/monitoring/jeck.ru

  3. # Сандер:

    Отлично, вставил сюда ссылку
    http://it.sander.su/status-code.php
    На самом деле, когда писал ту статью, как сразу подобного сервиса и не нашел. Сам-то из консоли Линукс проверяю.

    А подписка на комментарии – вещь полезная. Это я проверяю не появился ли ответ на странице, а многие и не будут. Правда, я в WP не разбираюсь, поэтому не могу точный совет дать. Только знаю, это всегда установкой модулей делается, как и в моем любимом Drupal, на котором сделан мой форум. Заходи, кстати!

  4. # Дмитрий:

    А можно пример как с помощью данного класса отправить кукисы, у меня что-т не получается.

  5. # Jeck:

    Дмитрий, ага я там поменял не много. Сейчас примерно так
    $http = new http;
    $http->cookies['example.com'] = array(
    'cookie_name_1' => 'cookie_value_1',
    'cookie_name_2' => 'cookie_value_2',
    );
    $page = $http->get('http://example.com');

    Это устанавливает куки для домена example.com если же не важно для какого домена то можно так:
    $http->cookies['.'] = array(
    'cookie_name_1' => 'cookie_value_1',
    'cookie_name_2' => 'cookie_value_2',
    );

    Должно работать. Если что то не будет – можно прям на email писать, баги в этой либе для меня очень важны :)

  6. # Дмитрий:

    Не так давно наткнулся на этот класс.
    Сам давно собирался написать что то подобное, но все руди не доходили. И вот нашолся добрый человек который это сделал и выложил в открытый доступ, СПАСИБО Вам ОГРОМНОЕ.
    Но при работе с классом заметил маленький баг (
    Если нужно получить страницу в определенной кодировке, например (utf-8 или windows-1251), а кодировка страницы донора в ее заголовке CP-1251 то класс после фукнкции iconv вернет false.
    Чтобы долго не думать, для себя решил эту проблемму следующим образом:
    после 206 строки вставил if(strtolower($this->encoding)==’cp-1251′){$this->encoding=’cp1251′;}

  7. # Андрей:

    Немного дополнил для того что бы работать с прокси по аунтификации
    private function setProxy() {
    if (!empty($this->proxy)) {
    curl_setopt($this->ch, CURLOPT_PROXY, $this->proxy);
    curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, “redmago:hunatilla1310″);
    curl_setopt($this->ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    curl_setopt($this->ch, CURLOPT_HTTPPROXYTUNNEL, 0);
    curl_setopt($this->ch, CURLOPT_PROXYTYPE, $this->proxy_type);

    }
    }

  8. # GTAlex:

    На некоторых косячных урлах возникает ошибка
    “maximum function nesting level of 100 reached aborting” из за бесконечной рекурсии в методе get

    пришлось чуток подкорректировать:
    1. добавил метод get_int (копия get), но с $this->loop++ и проверкой при рекурсивном вызове на $this->loop max_loop
    2. из get поставил вызов get_int с обнулением $this->loop

    и в конструкторе $this->max_loop = 3 (вполне достаточно)