ФорумПрограммированиеПыхнуть хотите?Готовые решения → Extra CURL - простой курл

Extra CURL - простой курл

  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 15 декабря 2010 г. 11:29

    Простой курл в фантике, попрошу оценить

    Спустя 20 сек.
    Вот весь код класса:

    <?php
    /*
    @ Extra LibCurl Class
    @ Version: 1.0.1
    @ Author: Mars
    @ PhpRequired: 5.3

    * Описание и помощь в использовании *
    —————————————————-
    - подключение класса выполняется примерно так: require_once 'extra.curl.php'; $curl = new libcurl;
    - одно соединение CURL называется поинтом (point)
    - поинт может содержать свои переменные, список переменных опубликован ниже
    - чтобы создать новый поинт используйте функции point или upoint:

    использование функции point:
    $curl->point('ch', array('url' => 'http://example.com'));

    менее объёмный по записи аналог предыдущей функции:
    $curl->upoint('http://example.com');

    быстрое выполнение запроса:
    echo $curl->point('ch', array('url' => 'http://example.com'))->exec();
    echo $curl->upoint('http://example.com')->exec();

    или так (быстрая запись результата в файл):
    file_put_contents('log.txt', $curl->upoint('http://example.com')->exec());

    использование нескольких поинтов (многопоточность):
    $curl->upoint('http://example.com');
    $curl->upoint('http://google.com');
    $curl->upoint('http://yandex.ru');
    $curl();

    или так:
    $curl->point('ch', array('url' => 'http://example.com'));
    $curl->point('ch', array('url' => 'http://google.com'));
    $curl->point('ch', array('url' => 'http://yandex.ru'));
    $curl();

    подсказка: можно использовать $curl(); или $curl->exec(); (это синонимы друг друга)

    - вы можете манипулировать поинтами используя активные переменные

    манипуляция с поинтами:
    * если задавать поинт через upoint, он автоматически приобретает порядковое имя chX, где X это его порядковый номер начиная с нуля (ch0, ch1, ch2 и тд…)
    * если вы задаёте поинт вручную, то вы сами указываете его имя
    * не рекомендуется использовать верхний регистр имён переменных (опций)
    * переменные окружения поинта - это есть опции потока curl на этом поинте, они такие же как и при указании curl_setopt, но без приставки CURLOPT_ и в нижнем регистре

    $curl->upoint('http://example.com');
    $curl->ch0->returntransfer = 0; // вывести результат прямо на экран
    $curl->exec();

    $curl->point('xch', array('url' => 'http://example.com'));
    $curl->xch->httpheader = array('blablabla'); // задать заголовок blablabla
    echo $curl->exec();

    задание сразу нескольких поинтов через set:
    $curl->point('xch', array('url' => 'http://example.com'));
    $myoptions = array('useragent' => 'Mozilla', 'header' => 1, 'followlocation' => 1);
    $curl->xch->set($myoptions); $result = $curl(); echo $result;

    ещё примеры манипуляций:
    $curl->upoint('http://example.com');
    $curl->ch0->header = 1;
    file_put_contents('log.txt', $curl());

    узнать текущее значение опции:
    echo $curl->xch->url ? : 'url не задан';

    использование коммутатора "and" с "upoint":
    $curl->upoint('http://google.ru')->and->followlocation = 1;
    $curl->upoint('http://example.com');
    $result = $curl->exec();
    file_put_contents('log.txt', serialize($result));

    ещё пример с "upoint", "and" и "set":
    $curl->upoint('http://google.ru')->and->set(array(
    'followlocation' => true,
    'header' => true,
    'fresh_connect' => true,
    ));

    file_put_contents('log.txt', $curl());

    использование secure() для поинтов позволяет использовать их несколько раз:
    $curl->upoint('http://google.ru')->and->secure()->set(array(
    'followlocation' => true,
    'header' => true,
    'fresh_connect' => true,
    ));
    $curl(); $curl(); $curl();
    file_put_contents('log.txt', $curl());

    ещё пример с отключением защиты:
    $curl->upoint('http://google.ru')->and->set(array(
    'followlocation' => true,
    'header' => true,
    'fresh_connect' => true,
    ))->secure();
    $curl->exec();
    $curl->and->secure(false); // в данном случае and является симлинком на ch0
    $curl->exec(); // сработало
    file_put_contents('log.txt', (!$curl())?'не сработало':'сработало'); // не сработало

    парсинг cookies:
    $result = $curl->point('ch', array('url' => 'http://vk.com', 'header' => 1))->exec();
    var_dump(libcurl::parse_cookies($result));

    препаринг cookies:
    $result = $curl->point('ch', array('url' => 'http://vk.com', 'header' => 1))->exec();
    $mycookies = libcurl::parse_cookies($result);
    echo libcurl::prepare_cookies($mycookies);

    - передавать параметры поинтам рекомендуется в верхнем регистре
    - по умолчанию любой поинт получает дополнительные два параметра (если они еще не заданы): header 0 и returntransfer 1
    - основной класс libcurl не упрощает использование curl, а лишь переносит его структуру на ООП, что может быть удобным для кода
    - также приложены расширяющие классы, вы можете использовать их для удобного кодинга приложений
    - для CURLINFO_, CURLCLOSEPOLICY_, CURLE_ используйте info::, closepolicy:: и e:: (например info::total_time)

    * список некоторых параметров *
    url - URL, с которым будет производиться операция
    infilesize - при закачке файла на удаленный сервер, следует использовать этот параметр для указания ожидаемого размера файла
    verbose - при установке этого параметра в ненулевое значение cURL будет выводить подробные сообщения о всех производимых действиях
    header - при установке этого параметра в ненулевое значение результат будет включать полученные заголовки
    noprogress - при установке этого параметра в ненулевое значение не будет выводиться индикатор прогресса операции
    nobody - при установке этого параметра в ненулевое значение результат не будет включать документ (например, вам нужно получить только заголовки)
    failonerror - при установке этого параметра в ненулевое значение, получение HTTP кода более 300 считается ошибкой
    upload - установка этого параметра в ненулевое значение означает, что будет производиться закачка файла на удаленный сервер
    post - при установке этого параметра в ненулевое значение будет отправлен HTTP запрос методом POST типа application/x-www-form-urlencoded, используемый браузерами при отправке форм
    ftplistonly - при установке этого параметра в ненулевое значение будет получен список файлов в директории FTP сервера
    followlocation - при установке этого параметра в ненулевое значение, при получении HTTP заголовка "Location: " будет происходить перенаправление на указанный этим заголовком URL (это действие выполняется рекурсивно, для каждого полученного заголовка "Location:")
    referer - задает значение HTTP заголовка "Referer: "
    */


    class libcurl
    {
    /* данные о поинтах */
    public $points = array();

    /* point ([строка point name, массив point data]) - добавить поинт */
    public function point($pn=false, $pointdata=false)
    {
    $point_name = (!$pn) ? 'ch'.count($this->points) : $pn;
    $this->$point_name = new curlpoint($pointdata);
    $this->points[] = $point_name;
    $this->and = $this->$point_name;
    return $this;
    }

    /* upoint (строка URL) - быстро добавить поинт без указания имени, но с указанием URL */
    public function upoint($url)
    {
    return $this->point(false, array('URL' => $url));
    }

    private function join_option($option)
    {
    $token = strtok($option, '::');
    switch($token)
    {
    case 'info': return constant('CURLINFO_'.strtoupper($option)); break;
    case 'closepolicy': return constant('CURLCLOSEPOLICY_'.strtoupper($option)); break;
    case 'e': return constant('CURLE_'.strtoupper($option)); break;
    default: return constant('CURLOPT_'.strtoupper($option));
    }
    }

    /* парсинг куков в массив */
    public static function parse_cookies($req)
    {
    preg_match_all('/Set-Cookie:\040(.+?)(\n|$)/s', $req, $cookies_requested);
    return (isset($cookies_requested[1])) ? $cookies_requested[1] : false;
    }

    /* приведение массива с кукисами к нормальному виду, пригодному для отправки через curl */
    public static function prepare_cookies($req)
    {
    return trim(preg_replace(array('/((expires|path|domain)=.+?|secure|httponly|\S+=deleted)(;|$)/', '/\s\s/'), array('', ' '), str_replace(
    array("\n", "\r", ';;'), array('', '', ';'), implode('; ', $req)
    )));
    }

    /* exec () - выполнить все поинты */
    public function exec()
    {
    $cp = count($this->points);

    if ($cp == 0)
    {
    return false;
    }
    elseif ($cp == 1)
    {
    $ch = curl_init(); $point_name = $this->points[0]; $ps = $this->$point_name->params;
    if ($ps) {foreach ($ps as $k=>$v) curl_setopt($ch, $this->join_option($k), $v);
    $data = curl_exec($ch);} curl_close($ch); if (!$this->$point_name->s) unset($this->$point_name);
    return $data;
    }
    else
    {
    $index = 0; $channels = array(); $return_array = array();
    foreach ($this->points as $point_name)
    {
    $index++; $chname = 'ch'.$index; $$chname = curl_init(); $ps = $this->$point_name->params;
    foreach ($ps as $k=>$v) curl_setopt($$chname, $this->join_option($k), $v);
    if (!$this->$point_name->s) {unset($this->$point_name);} $channels[] = $chname;
    }

    $mh = curl_multi_init();

    foreach ($channels as $chof)
    {
    curl_multi_add_handle($mh, $$chof);
    }

    $active = null;

    do {
    $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
    do {
    $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
    }

    foreach ($channels as $chof)
    {
    $content = curl_multi_getcontent($$chof);
    if (!empty($content)) $return_array[] = $content;
    curl_multi_remove_handle($mh, $$chof);
    }

    curl_multi_close($mh);

    return $return_array;
    }
    }

    public function __invoke()
    {
    return $this->exec();
    }
    }

    class curlpoint
    {
    public $params = array();
    public $s = false;

    public function __construct($pdata)
    {
    $pdata['header']?:$pdata['header']=0;
    $pdata['returntransfer']?:$pdata['returntransfer']=1;
    $this->set($pdata);
    }

    public function __set($name, $value)
    {
    if ($name !== 's') $this->params[$name] = $value;
    }

    public function set($pdata)
    {
    foreach ($pdata as $key => $value)
    {
    $this->$key = $value;
    }
    return $this;
    }

    public function secure($key=true)
    {
    $this->s = $key;
    return $this;
    }

    }
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 15 декабря 2010 г. 11:34, спустя 5 минут 2 секунды

    оо зародыш Дудкурла :-)
    Сапожник без сапог
  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 15 декабря 2010 г. 11:43, спустя 8 минут 41 секунду

    Твой дудкурл больно охуенный, это вариант попроще
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 15 декабря 2010 г. 11:52, спустя 8 минут 51 секунду

    за мне как бы совершенно похуй :-) они проект заброшен, туда ему и дорога :-) свои задачи с меня выполняет и гут:-) чего то я расплакался, пошел посплю
    Спустя 86 сек.
    за мне как бы совершенно похуй :-) они проект заброшен, туда ему и дорога :-) свои задачи с меня выполняет и гут:-) чего то я расплакался, пошел посплю
    Сапожник без сапог
  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 15 декабря 2010 г. 11:54, спустя 2 минуты 1 секунду

    а я аватарку поменял…
  • Frozzeg

    Сообщения: 5641 Репутация: N Группа: Джедаи

    Spritz 15 декабря 2010 г. 20:16, спустя 8 часов 22 минуты 31 секунду

    стиль кода ужасен
    You can be anything you want to be. Just turn yourself into anything you think that you could ever be.
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 16 декабря 2010 г. 9:13, спустя 12 часов 56 минут 27 секунд

    покажи как сделал бы ты, может переучусь

    он выкладывал ищи по DudeCURL
  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 16 декабря 2010 г. 10:51, спустя 1 час 38 минут 19 секунд

    Немного дописал код класса, добавил пару новых функций.

    Вот пример авторизации вконтакте при помощи этого класса:

    <?php
    require_once 'extra.curl.php'; $curl = new libcurl;

    # логин и пароль
    $login = 'мой@маил';
    $password = 'мой пароль';

    # получаем кукисы авторизованного
    $auth = libcurl::cookies($curl->ipoint(array(
    'url' => 'http://login.vk.com/?act=login',
    'postfields' => 'act=login&q=1&al_frame=1&from_host=vkontakte.ru&email='.$login.'&pass='.$password,
    'referer' => 'http://vkontakte.ru/',
    'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12',
    'followlocation' => 1,
    'header' => 1))->exec());

    # проверяем полученные cookies
    file_put_contents('log.txt', $auth);


    и да, мне кажется мой говнокод относительно нормальный, просто вы уже надрочились на свои пхпдоки и пишете во всяких IDE
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 16 декабря 2010 г. 10:53, спустя 2 минуты 16 секунд

    Mars, поверишь что даже emacs и vim понимает phpDoc?
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 16 декабря 2010 г. 11:00, спустя 7 минут 7 секунд

    свои пхпдоки и пишете во всяких IDE

    ебать, так это ж стандарт
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 16 декабря 2010 г. 11:08, спустя 7 минут 11 секунд

    пхпдоки не главное в коде … главное - код
    Сапожник без сапог
  • andipas

    Сообщения: 170 Репутация: N Группа: Кто попало

    Spritz 16 декабря 2010 г. 11:12, спустя 4 минуты 44 секунды

    нормальный стиль кода
    с phpDoc - конечно было б лучше
  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 16 декабря 2010 г. 12:48, спустя 1 час 36 минут 11 секунд

    очередной апдейт, чуть больше документированности в начале класса и дополнительный дочерний расширяющий класс easy_libcurl
    если инициализировать его вместо libcurl, то вы получите:
    - удобная симуляция браузера
    - использование CURLOPT_AUTOREFERER
    - автодобавление заголовков к поинтам основного класса

    class easy_libcurl extends libcurl
    {
    # Constructor __construct
    public function __construct()
    {
    $this->http = array();
    $this->http[] = 'Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1';
    $this->http[] = 'Accept-Language: en';
    $this->http[] = 'Pragma: no-cache';

    $this->browser = array(
    'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12',
    'followlocation' => 1,
    'timeout' => 10,
    'autoreferer' => true,
    'returntransfer' => true,
    'header' => true,
    'httpheader' => $this->http,
    );
    }

    # void point ([ $pn = false], [ $pointdata = false])
    public function point($pn=false, $pointdata=false)
    {
    return parent::point($pn, array_merge($pointdata, $this->browser));
    }
    }
  • Mars

    Сообщения: 304 Репутация: N Группа: Кто попало

    Spritz 16 декабря 2010 г. 13:08, спустя 19 минут 40 секунд

    вот авторизация вконтакте при помощи easy_libcurl вместо libcurl

    <?php
    require_once 'extra.curl.php';
    $curl = new easy_libcurl;

    # логин и пароль
    $login = '************';
    $password = '***********';

    # получаем кукисы авторизованного
    $auth = libcurl::cookies($curl->ipoint(array(
    'url' => 'http://login.vk.com/?act=login',
    'postfields' => "act=login&q=1&al_frame=1&from_host=vkontakte.ru&email=$login&pass=$password",
    'referer' => 'http://vkontakte.ru/',
    ))->exec());

    # проверяем полученные cookies
    file_put_contents('log.txt', $auth);
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 16 декабря 2010 г. 14:51, спустя 1 час 43 минуты 12 секунд

    ой да ладно, что вы напали на человека? либа и либа
    Спустя 138 сек.
    Mars, как это

        public function sendHttpRequest($requestXml)
    {
    $curl = curl_init();
    //set the server we are using (could be Sandbox or Production server)
    curl_setopt($curl, CURLOPT_URL, $this->apiParams['server_url']);

    // stop CURL from verifying the peer's certificate
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

    // set the headers using the array of headers
    $this->logData['request_headers'] = $headers = $this->buildEbayHeaders();
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

    curl_setopt($curl, CURLOPT_POST, 1);

    // set the XML body of the request
    $this->logData['request'] = $requestXml;
    curl_setopt($curl, CURLOPT_POSTFIELDS, $requestXml);

    // set it to return the transfer as a string from curl_exec
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $responseXml = curl_exec($curl);
    $this->logData['response'] = $responseXml;
    curl_close($curl);

    return $responseXml;
    }

    будет выглядеть с твоей либой?

Пожалуйста, авторизуйтесь, чтобы написать комментарий!