Print curl error

(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)

(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)

curl_errorReturn a string containing the last error for the current session

Description

Parameters

handle

A cURL handle returned by
curl_init().

Return Values

Returns the error message or '' (the empty string) if no
error occurred.

Changelog

Version Description
8.0.0 handle expects a CurlHandle
instance now; previously, a resource was expected.

Examples

Example #1 curl_error() example


<?php
// Create a curl handle to a non-existing location
$ch = curl_init('http://404.php.net/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

if(

curl_exec($ch) === false)
{
echo
'Curl error: ' . curl_error($ch);
}
else
{
echo
'Operation completed without any errors';
}
// Close handle
curl_close($ch);
?>

patrick at ibuildings dot nl

9 years ago


If you want to fetch the error message, make sure you fetch it before you close the current cURL session or the error message will be reset to an empty string.

paul at paulmcgarry dot com

14 years ago


For a 404 response to actually trigger an error as the example seems to be trying to demonstrate the following option should be set:

curl_setopt($ch,CURLOPT_FAILONERROR,true);

As per http://curl.haxx.se/libcurl/c/libcurl-errors.html

CURLE_HTTP_RETURNED_ERROR (22)
This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server returns an error code that is >= 400. (This error code was formerly known as CURLE_HTTP_NOT_FOUND.)


anrdaemon at freemail dot ru

3 years ago


curl_error is not a textual representation of curl_errno.
It's an actual error *message*.
If you want textual representation of error *code*, look for curl_strerror.

Anonymous

2 years ago


If you're using curl_multi and there's an error, curl_error() will remain empty until you've called curl_multi_info_read(). That function "pumps" the information inside the curl libraries to the point where curl_error() will return a useful string.

This should really be added to the documentation, because it's not at all obvious.


Troubleshooting

Debug using the diagnose method

$curl = new Curl();
$curl->get('https://www.example.com/');
$curl->diagnose(); // <-- HERE

Debug the entire curl instance

$curl = new Curl();
$curl->get('https://www.example.com/');
var_dump($curl); // <-- HERE

Ensure you have the latest version of the library installed

$ cd php-curl-class/
$ composer update
$ composer info

Compare your version with latest release which is also listed on the releases page.

Ensure php is using the latest version of curl

$ php -r 'var_dump(curl_version());'

Compare your version of curl with latest release which is also listed on curl’s releases page.

Turn on error reporting

Print some information that may hint at the cause of failure

error_reporting(E_ALL);
$curl = new Curl();
$curl->get('https://www.example.com/');
echo 'error: ' . $curl->error . "n";
echo 'errorCode: ' . $curl->errorCode . "n";
echo 'errorMessage: ' . $curl->errorMessage . "n";
echo 'curlError: ' . $curlError . "n";
echo 'curlErrorCode: ' . $curlErrorCode . "n";
echo 'curlErrorMessage: ' . $curlErrorMessage . "n";
echo 'httpError: ' . $httpError . "n";
echo 'httpStatusCode: ' . $httpStatusCode . "n";
echo 'httpErrorMessage: ' . $httpErrorMessage . "n";
echo 'requestHeaders:' . "n";
var_dump($curl->requestHeaders);
echo 'responseHeaders:' . "n";
var_dump($curl->responseHeaders);

Turn on verbose mode

error_reporting(E_ALL);
$curl = new Curl();
$curl->verbose();
$curl->get('https://www.example.com/');
var_dump($curl);

Compare request with and without the library

error_reporting(E_ALL);
$curl = new Curl();
$curl->get('https://www.example.com/');
var_dump($curl);
error_reporting(E_ALL);
$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 'https://www.example.com/');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPGET, true);
$raw_response = curl_exec($ch);
$curl_error_code = curl_errno($ch);
$curl_error_message = curl_error($ch);
$http_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$request_headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
var_dump($http_status_code);
var_dump($curl_error_code);
var_dump($curl_error_message);
var_dump($request_headers);
var_dump($raw_response);

Ensure you have the latest version of composer installed

$ composer self-update
$ composer --version

Compare your version of composer with latest release which is also listed on composer’s releases page.

Я использую функции PHP curl для отправки данных на веб-сервер с моей локальной машины. Мой код выглядит следующим образом:

$c = curl_init();

curl_setopt($c, CURLOPT_URL, $url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

curl_setopt($c, CURLOPT_POST, true);

curl_setopt($c, CURLOPT_POSTFIELDS, $data);

$result = curl_exec($c);

if (curl_exec($c) === false) {

    echo «ok»;

} else {

    echo «error»;

}

curl_close($c);

 К сожалению, я не могу поймать ни одной ошибки типа 404, 500 или сетевого уровня. Как же мне узнать, что данные не были размещены или получены с удаленного сервера?

Ответ 1

Вы можете использовать функцию curl_error(), чтобы определить, произошла ли какая-то ошибка. Например:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $your_url);

curl_setopt($ch, CURLOPT_FAILONERROR, true); // Требуется для того, чтобы коды ошибок HTTP сообщались через наш вызов к curl_error($ch)

//…

curl_exec($ch);

if (curl_errno($ch)) {

    $error_msg = curl_error($ch);

}

curl_close($ch);

if (isset($error_msg)) {

    // TODO — Обработать ошибку cURL соответствующим образом

}

Ответ 2

Если CURLOPT_FAILONERROR равно false, ошибки http не будут вызывать ошибок curl.

<?php

if (@$_GET[‘curl’]==»yes») {

  header(‘HTTP/1.1 503 Service Temporarily Unavailable’);

} else {

  $ch=curl_init($url = «http://».$_SERVER[‘SERVER_NAME’].$_SERVER[‘PHP_SELF’].»?curl=yes»);

  curl_setopt($ch, CURLOPT_FAILONERROR, true);

  $response=curl_exec($ch);

  $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

  $curl_errno= curl_errno($ch);

  if ($http_status==503)

    echo «HTTP Status == 503 <br/>»;

  echo «Curl Errno returned $curl_errno <br/>»;

}

Ответ 3

Вы можете сгенерировать ошибку curl после его выполнения:

$url = ‘http://example.com’;

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);

if(curl_errno($ch)){

    echo ‘Request Error:’ . curl_error($ch);

}

 И вот коды ошибок curl:

если кому-то нужна дополнительная информация об ошибках curl

<?php

    $error_codes=array(

    [1] => ‘CURLE_UNSUPPORTED_PROTOCOL’,

    [2] => ‘CURLE_FAILED_INIT’,

    [3] => ‘CURLE_URL_MALFORMAT’,

    [4] => ‘CURLE_URL_MALFORMAT_USER’,

    [5] => ‘CURLE_COULDNT_RESOLVE_PROXY’,

    [6] => ‘CURLE_COULDNT_RESOLVE_HOST’,

    [7] => ‘CURLE_COULDNT_CONNECT’,

    [8] => ‘CURLE_FTP_WEIRD_SERVER_REPLY’,

    [9] => ‘CURLE_REMOTE_ACCESS_DENIED’,

    [11] => ‘CURLE_FTP_WEIRD_PASS_REPLY’,

    [13] => ‘CURLE_FTP_WEIRD_PASV_REPLY’,

    [14]=>’CURLE_FTP_WEIRD_227_FORMAT’,

    [15] => ‘CURLE_FTP_CANT_GET_HOST’,

    [17] => ‘CURLE_FTP_COULDNT_SET_TYPE’,

    [18] => ‘CURLE_PARTIAL_FILE’,

    [19] => ‘CURLE_FTP_COULDNT_RETR_FILE’,

    [21] => ‘CURLE_QUOTE_ERROR’,

    [22] => ‘CURLE_HTTP_RETURNED_ERROR’,

    [23] => ‘CURLE_WRITE_ERROR’,

    [25] => ‘CURLE_UPLOAD_FAILED’,

    [26] => ‘CURLE_READ_ERROR’,

    [27] => ‘CURLE_OUT_OF_MEMORY’,

    [28] => ‘CURLE_OPERATION_TIMEDOUT’,

    [30] => ‘CURLE_FTP_PORT_FAILED’,

    [31] => ‘CURLE_FTP_COULDNT_USE_REST’,

    [33] => ‘CURLE_RANGE_ERROR’,

    [34] => ‘CURLE_HTTP_POST_ERROR’,

    [35] => ‘CURLE_SSL_CONNECT_ERROR’,

    [36] => ‘CURLE_BAD_DOWNLOAD_RESUME’,

    [37] => ‘CURLE_FILE_COULDNT_READ_FILE’,

    [38] => ‘CURLE_LDAP_CANNOT_BIND’,

    [39] => ‘CURLE_LDAP_SEARCH_FAILED’,

    [41] => ‘CURLE_FUNCTION_NOT_FOUND’,

    [42] => ‘CURLE_ABORTED_BY_CALLBACK’,

    [43] => ‘CURLE_BAD_FUNCTION_ARGUMENT’,

    [45] => ‘CURLE_INTERFACE_FAILED’,

    [47] => ‘CURLE_TOO_MANY_REDIRECTS’,

    [48] => ‘CURLE_UNKNOWN_TELNET_OPTION’,

    [49] => ‘CURLE_TELNET_OPTION_SYNTAX’,

    [51] => ‘CURLE_PEER_FAILED_VERIFICATION’,

    [52] => ‘CURLE_GOT_NOTHING’,

    [53] => ‘CURLE_SSL_ENGINE_NOTFOUND’,

    [54] => ‘CURLE_SSL_ENGINE_SETFAILED’,

    [55] => ‘CURLE_SEND_ERROR’,

    [56] => ‘CURLE_RECV_ERROR’,

    [58] => ‘CURLE_SSL_CERTPROBLEM’,

    [59] => ‘CURLE_SSL_CIPHER’,

    [60] => ‘CURLE_SSL_CACERT’,

    [61] => ‘CURLE_BAD_CONTENT_ENCODING’,

    [62] => ‘CURLE_LDAP_INVALID_URL’,

    [63] => ‘CURLE_FILESIZE_EXCEEDED’,

    [64] => ‘CURLE_USE_SSL_FAILED’,

    [65] => ‘CURLE_SEND_FAIL_REWIND’,

    [66] => ‘CURLE_SSL_ENGINE_INITFAILED’,

    [67] => ‘CURLE_LOGIN_DENIED’,

    [68] => ‘CURLE_TFTP_NOTFOUND’,

    [69] => ‘CURLE_TFTP_PERM’,

    [70] => ‘CURLE_REMOTE_DISK_FULL’,

    [71] => ‘CURLE_TFTP_ILLEGAL’,

    [72] => ‘CURLE_TFTP_UNKNOWNID’,

    [73] => ‘CURLE_REMOTE_FILE_EXISTS’,

    [74] => ‘CURLE_TFTP_NOSUCHUSER’,

    [75] => ‘CURLE_CONV_FAILED’,

    [76] => ‘CURLE_CONV_REQD’,

    [77] => ‘CURLE_SSL_CACERT_BADFILE’,

    [78] => ‘CURLE_REMOTE_FILE_NOT_FOUND’,

    [79] => ‘CURLE_SSH’,

    [80] => ‘CURLE_SSL_SHUTDOWN_FAILED’,

    [81] => ‘CURLE_AGAIN’,

    [82] => ‘CURLE_SSL_CRL_BADFILE’,

    [83] => ‘CURLE_SSL_ISSUER_ERROR’,

    [84] => ‘CURLE_FTP_PRET_FAILED’,

    [84] => ‘CURLE_FTP_PRET_FAILED’,

    [85] => ‘CURLE_RTSP_CSEQ_ERROR’,

    [86] => ‘CURLE_RTSP_SESSION_ERROR’,

    [87] => ‘CURLE_FTP_BAD_FILE_LIST’,

    [88] => ‘CURLE_CHUNK_FAILED’);

    ?>

Ответ 4

Поскольку вы заинтересованы в отлове ошибок, связанных с сетью, и ошибок HTTP, ниже приведен лучший подход:

function curl_error_test($url) {

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseBody = curl_exec($ch);

    /*

     * if curl_exec failed then

     * $responseBody равно false

     * curl_errno() возвращает ненулевое число

     * curl_error() возвращает непустую строку

     * Какой из них использовать — решать вам

     */

    if ($responseBody === false) {

        return «CURL Error: » . curl_error($ch);

    }

    $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    /*

     * 4xx коды состояния — ошибки клиента

     * 5xx коды состояния — ошибки сервера

     */

    if ($responseCode >= 400) {

        return «HTTP Error: » . $responseCode;

    }

    return «Нет ошибки CURL или HTTP «;

}

 Тесты:

curl_error_test(«http://expamle.com»);          //  Ошибка CURL : Невозможно определить хост : expamle.com

curl_error_test(«http://example.com/whatever»); // Ошибка HTTP: 404

curl_error_test(«http://example.com»);          // Все в порядке с CURL или HTTP

Ответ 5

Еще один вариант кода:

  $responseInfo = curl_getinfo($ch);

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

    $body = substr($response, $header_size);

    $result=array();

    $result[‘httpCode’]=$httpCode;

    $result[‘body’]=json_decode($body);

    $result[‘responseInfo’]=$responseInfo;

    print_r($httpCode); 

     print_r($result[‘body’]); exit;

    curl_close($ch);

    if($httpCode == 403) {

        print_r(«Доступ запрещен»);

        exit;

    }   else {

         // другие ошибки 

     }

PHP поддерживает libcurl, библиотеку, созданную Daniel»ом Stenberg»ом,
которая даёт возможность соединяться с серверами различных типов и по разным протоколам.
libcurl в настоящее время поддерживает протоколы http, https, ftp, gopher, telnet, dict, file и ldap.
libcurl также поддерживает сертификаты HTTPS, HTTP POST, HTTP PUT, загрузку по FTP (это можно сделать также РНР-расширением ftp),
загрузку на основе форм HTTP, прокси, куки и аутентификацию user+password.

Эти функции были введены в PHP 4.0.2.

curl_init

curl_init — инициализирует CURL-сессию.

Описание

resource curl_init([string url])

Функция curl_init() инициализирует новую сессию и возвратит CURL-дескриптор для
использования в функциях curl_setopt(),
curl_exec() и curl_close().
Если необязательный параметр url предоставлен, то опция
CURLOPT_URL получит значение этого параметра. Вы можете вручную устанавливать его с помощью функции
curl_setopt().

curl_setopt

curl_setopt — устанавливает опции для CURL-трансфера/transfer.

Описание

bool curl_setopt (resource ch, string option, mixed value)

Функция curl_setopt() устанавливает опции для CURL-сессии, идентифицируемой параметром ch.
Параметр option является опцией, которую вы хотите установить, а value это значение опции
option.

Параметр value должен быть long для следующих опций (специфицированных параметром option):

  • CURLOPT_INFILESIZE: Если вы выгружаете файл на удалённый сайт, эта опция должна использоваться,
    для того чтобы сообщит PHP, какой будет ожидаемый размер infile.
  • CURLOPT_VERBOSE: Установите эту опцию в ненулевое значение, если вы хотите, чтобы CURL
    сообщала обо всех действиях.
  • CURLOPT_HEADER: Установите эту опцию в ненулевое значение, если вы хотите, чтобы шапка/header
    включалась в вывод.
  • CURLOPT_NOPROGRESS: Установите эту опцию в ненулевое значение, если вы не хотите, чтобы PHP
    выводил индикатор процесса CURL-трансфера.
    (PHP автоматически устанавливает эту опцию в ненулевое значение, изменять её необходимо лишь при отладке.)
  • CURLOPT_NOBODY: Установите эту опцию в ненулевое значение, если вы не хотите, чтобы тело/body
    включалось в вывод.
  • CURLOPT_FAILONERROR: Установите эту опцию в ненулевое значение, если вы хотите, чтобы PHP завершал
    работу скрыто, если возвращаемый HTTP-код имеет значение выше 300. По
    умолчанию страница возвращается нормально с игнорированием кода.
  • CURLOPT_UPLOAD: Установите эту опцию в ненулевое значение, если вы хотите, чтобы PHP
    подготавливал файл к выгрузке.
  • CURLOPT_POST: Установите эту опцию в ненулевое значение, если вы хотите, чтобы PHP выполнял
    регулярный HTTP POST. Этот POST имеет нормальный вид application/x-www-form-urlencoded, чаще всего используемый HTML-формами.
  • CURLOPT_FTPLISTONLY: Установите эту опцию в ненулевое значение, и PHP будет выводит листинг имён FTP-директории.
  • CURLOPT_FTPAPPEND: Установите эту опцию в ненулевое значение, и PHP будет присоединять к
    удалённому/remote файлу, вместо его перезаписи.
  • CURLOPT_NETRC: Установите эту опцию в ненулевое значение, и PHP будет сканировать ваш файл
    ~./netrc с целью поиска ваших username и password для удалённого сайта, с которым вы
    устанавливаете соединение.
  • CURLOPT_FOLLOWLOCATION: Установите эту опцию в ненулевое значение, чтобы следовать любому «Location: » header,
    который сервер высылает как часть HTTP header»а (заметьте,
    что это рекурсия, PHP будет следовать за всеми «Location: «-header»ами, которые высылаются.)
  • CURLOPT_PUT: Установите эту опцию в ненулевое значение, чтобы HTTP PUT файл. Файл для PUT
    обязан быть установлен с помощью CURLOPT_INFILE и CURLOPT_INFILESIZE.
  • CURLOPT_MUTE: Установите эту опцию в ненулевое значение, и PHP будет работать скрыто в
    отношении CURL-функций.
  • CURLOPT_TIMEOUT: Передаёт long как параметр, который содержит максимальное время в секундах,
    которое вы отводите для работы CURL-функций.
  • CURLOPT_CONNECTTIMEOUT: Передаёт long как параметр, который содержит максимальное время в секундах,
    которое вы отводите для ожидания при попытке подключения. Используйте 0 чтобы ждать бесконечно.
  • CURLOPT_LOW_SPEED_LIMIT: Передаёт long как параметр, который содержит скорость трансфера в байтах в
    секунду, ниже которого трансфер должен работать в процессе выполнения
    CURLOPT_LOW_SPEED_TIME, в секундах, чтобы PHP считал его слишком медленным и прерывал его.
  • CURLOPT_LOW_SPEED_TIME: Передаёт long как параметр, который содержит время в секундах, ниже которого
    трансфер должен работать в процессе выполнения CURLOPT_LOW_SPEED_LIMIT,
    чтобы PHP считал его слишком медленным и прерывал его.
  • CURLOPT_RESUME_FROM: Передаёт long как параметр, который содержит смещение в байтах, с которого
    трансфер должен стартовать.
  • CURLOPT_SSLVERSION: Передаёт long как параметр, который содержит используемую версию SSL (2 или 3).
    По умолчанию PHP пытается определить это сам, хотя в некоторых случаях вы обязаны устанавливать это вручную.
  • CURLOPT_SSL_VERIFYHOST: Передаёт long, если
    CURL должна проверять Common-имя peer-сертификата в SSL handshake/»рукопожатие». Значение 1 указывает, что мы должны
    проверить существование общего /common имени, значение 2 указывает, что мы
    должны убедиться в совпадении с предоставленным hostname.
  • CURLOPT_TIMECONDITION: Передаёт long как параметр, который определяет, как рассматривается CURLOPT_TIMEVALUE.
    Вы можете установить этот параметр для TIMECOND_IFMODSINCE или
    TIMECOND_ISUNMODSINCE. Это действует только для HTTP.
  • CURLOPT_TIMEVALUE: Передаёт long как параметр, который является временем в секундах, прошедшим
    после 1 января 1970. Это время используется, как специфицировано опцией CURLOPT_TIMEVALUE,
    или по умолчанию будет использоваться TIMECOND_IFMODSINCE.
  • CURLOPT_RETURNTRANSFER: Передаёт ненулевое значение, если вы хотите, чтобы CURL непосредственно
    возвращала полученную информацию, вместо её печати напрямую.

Параметр value должен быть строкой для следующих значений параметра option:

  • CURLOPT_URL: Это URL, который PHP должен получать. Вы можете также устанавливать эту
    опцию при инициализации сессии функцией curl_init().
  • CURLOPT_USERPWD: Передаёт в РНР строку, отформатированную в виде [username]:[password], для
    использования при соединении.
  • CURLOPT_PROXYUSERPWD: Передаёт в РНР строку, отформатированную в виде [username]:[password], для
    соединения с HTTP-прокси.
  • CURLOPT_RANGE:
    Передаёт специфицированный вами диапазон. Он должен быть в формате
    «X-Y», где X или Y могут отсутствовать. HTTP-трансферы поддерживают
    также различные интервалы, разделённые запятыми, как, например, X-Y,N-M.
  • CURLOPT_POSTFIELDS: Передаёт строку, содержащую полные данные для передачи операцией HTTP «POST».
  • CURLOPT_REFERER: Передаёт строку, содержащую «referer/ссылающийся» header, используемый в HTTP-запросе.
  • CURLOPT_USERAGENT: Передаёт строку, содержащую «user-agent» header, используемый в HTTP-запросе.
  • CURLOPT_FTPPORT: Передаёт строку, содержащую значение, которое будет использоваться для
    получения IP-адреса для инструкции ftp «POST». POST-инструкция указывает
    удалённому серверу: соединиться со специфицированным IP-адресом. Строка
    может быть обычным IP-адресом, hostname/именем хоста, именем сетевого
    интерфейса (под UNIX), или просто обычным «-«, используемым для системного IP-адреса по умолчанию.
  • CURLOPT_COOKIE: Передаёт строку с содержимым куки/cookie, установленным в HTTP header»е.
  • CURLOPT_SSLCERT: Передаёт строку, содержащую filename форматированного сертификата PEM.
  • CURLOPT_SSLCERTPASSWD: Передаёт строку, содержащую password, необходимый для работы сертификата CURLOPT_SSLCERT.
  • CURLOPT_COOKIEFILE: Передаёт строку, содержащую имя файла с данными куки.
    Этот cookie-файл может иметь формат Netscape, или содержать обычные
    шапки/headers в HTTP-стиле, забитые в файл.
  • CURLOPT_CUSTOMREQUEST: Передаёт строку, используемую вместо
    GET или HEAD при выполнении HTTP-запроса. Это делается для выполнения DELETE или других, более скрытых HTTP-запросов.
    Верными значениями являются GET, POST и так далее; то есть не вводите здесь полную строку HTTP-запроса.
    Например, ввод «GET /index.html HTTP/1.0» будет некорректным.
    (не делайте это, если не уверены, что ваш сервер поддерживает эту команду.)
  • CURLOPT_PROXY: Передаёт имя HTTP-прокси туннельным запросам.
  • CURLOPT_INTERFACE: Передаёт имя исходящего сетевого интерфейса для использования. Это может
    быть имя интерфейса, IP-адрес или имя хоста.
  • ( curl_setopt($ch, CURLOPT_INTERFACE, $extip) )

  • CURLOPT_KRB4LEVEL: Передаёт KRB4 (Kerberos
    4) уровень секретности. Это любая из следующих строк (в порядке от менее до более мощной): «clear», «safe»,
    «confidential», «private».
    Если эта строка не совпадает с какой-либо из указанных, то используется «private».
    Если вы установите здесь NULL, это отключит KRB4-безопасность. KRB4-безопасность работает в настоящее
    время только с транзакциями FTP.
  • CURLOPT_HTTPHEADER: Передаёт массив полей HTTP-header»а для установки.
  • CURLOPT_QUOTE: Передаёт массив FTP-команд для выполнения на сервере до выполнения FTP-запроса.
  • CURLOPT_POSTQUOTE: Передаёт массив FTP-команд для выполнения на сервере после выполнения FTP-запроса.

Следующие опции ожидают дескриптора файла, который получается с помощью функции
fopen():

  • CURLOPT_FILE: Файл, куда должен быть помещён вывод вашего трансфера, по умолчанию это STDOUT.
  • CURLOPT_INFILE: Файл, из которого приходит ввод вашего трансфера.
  • CURLOPT_WRITEHEADER: Файл для записи header-части вывода.
  • CURLOPT_STDERR: Файл для записи ошибок, вместо stderr.

Параметр value должен быть функцией следующего вида
long write_callback (resource ch, string data){ … return strlen($data);}
для следующих значений параметра option:

  • CURLOPT_WRITEFUNCTION: .
  • CURLOPT_HEADERFUNCTION: .

Параметр value должен быть функцией следующего вида
string read_callback (resource ch, resource fd, long length){}
для следующих значений параметра option:

  • CURLOPT_READFUNCTION: .

curl_exec

curl_exec — выполняет CURL-сессию.

Описание

bool curl_exec (resource ch)

Эта функция должна вызываться после того, как вы инициализируете сессию CURL
и все опции этой сессии уже установлены. Её назначение в том, чтобы просто
выполнить предопределённую CURL-сессию (заданную в параметре ch).

curl_close

curl_close — закрывает CURL-сессию.

Описание

void curl_close ( resource ch)

Эта функция закрывает сессию CURL и освобождает все ресурсы.
CURL-дескриптор ch также удаляется.

curl_errno

curl_errno — возвращает целое число, содержащее номер последней ошибки.

Описание

int curl_errno ( resource ch)

curl_error

curl_error — возвращает строку содержащую номер последней ошибки для текущей сессии.

Описание

string curl_error (resource ch)

curl_getinfo

curl_getinfo — получает информацию, касающуюся специфической передачи/transfer.

Описание

string curl_getinfo (resource ch, int opt)


  • CURLINFO_EFFECTIVE_URL — Последний
    использованный URL

  • CURLINFO_HTTP_CODE — Последний полученный код
    HTTP

  • CURLINFO_FILETIME — Дата модификации
    загруженного документа, если она неизвестна, возвращается -1.

  • CURLINFO_TOTAL_TIME — Полное время выполнения
    операции в секундах.

  • CURLINFO_NAMELOOKUP_TIME — Время разрешения
    имени сервера в секундах.

  • CURLINFO_CONNECT_TIME — Время, затраченное на
    установку соединения, в секундах

  • CURLINFO_PRETRANSFER_TIME — Время, прошедшее
    от начала операции до готовности к фактической передаче данных, в
    секундах

  • CURLINFO_STARTTRANSFER_TIME — Время, прошедшее
    от начала операции до момента передачи первого байта данных, в
    секундах

  • CURLINFO_REDIRECT_TIME — Общее время,
    затраченное на перенапрвления, в секундах

  • CURLINFO_SIZE_UPLOAD — Количество байт при
    закачке

  • CURLINFO_SIZE_DOWNLOAD — Количество байт при
    загрузке

  • CURLINFO_SPEED_DOWNLOAD — Средняя скорость
    закачки

  • CURLINFO_SPEED_UPLOAD — Средняя скорость
    загрузки

  • CURLINFO_HEADER_SIZE — Суммарный размер всех
    полученных заголовков

  • CURLINFO_REQUEST_SIZE — Суммарный размер всех
    отправленных запросов, в настоящее время используется только для HTTP запросов

  • CURLINFO_SSL_VERIFYRESULT — Результат
    проверки SSL сертификата, запрошенной с помощью установки
    параметра CURLOPT_SSL_VERIFYPEER

  • CURLINFO_CONTENT_LENGTH_DOWNLOAD
    размер загруженного документа, прочитанный из заголовка
    Content-Length

  • CURLINFO_CONTENT_LENGTH_UPLOAD — Размер
    закачиваемых данных

  • CURLINFO_CONTENT_TYPE — Содержимое
    полученного заголовка Content-type, или NULL в случае, когда этот
    заголовок не был получен

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


  • «url»

  • «content_type»

  • «http_code»

  • «header_size»

  • «request_size»

  • «filetime»

  • «ssl_verify_result»

  • «redirect_count»

  • «total_time»

  • «namelookup_time»

  • «connect_time»

  • «pretransfer_time»

  • «size_upload»

  • «size_download»

  • «speed_download»

  • «speed_upload»

  • «download_content_length»

  • «upload_content_length»

  • «starttransfer_time»

  • «redirect_time»
Пример использования curl_getinfo:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);	// если этот параметр не указать не работает!
curl_exec($ch);
var_dump(curl_getinfo($ch,CURLINFO_HEADER_OUT));
Пример использования curl_getinfo:
$ch = curl_init(); // create cURL handle (ch)
if (!$ch) {
    die("Couldn't initialize a cURL handle");
}
// set some cURL options
$ret = curl_setopt($ch, CURLOPT_URL,            "http://mail.yahoo.com");
$ret = curl_setopt($ch, CURLOPT_HEADER,         1);
$ret = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$ret = curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
$ret = curl_setopt($ch, CURLOPT_TIMEOUT,        30);

// execute
$ret = curl_exec($ch);

if (empty($ret)) {
    // some kind of an error happened
    die(curl_error($ch));
    curl_close($ch); // close cURL handler
} else {
    $info = curl_getinfo($ch);
    curl_close($ch); // close cURL handler

    if (empty($info['http_code'])) {
            die("No HTTP code was returned");
    } else {
        // load the HTTP codes
        $http_codes = parse_ini_file("path/to/the/ini/file/I/pasted/above");

        // echo results
        echo "The server responded: <br />";
        echo $info['http_code'] . " " . $http_codes[$info['http_code']];
    }

}

curl_version

curl_version — возвращает версию текущей CURL.

Описание

string curl_version (void)

Функция curl_version() возвращает строку с текущей версией CURL.

curl_version=Array
(
[version_number] => 472065
[age] => 3
[features] => 4179869
[ssl_version_number] => 0
[version] => 7.52.1
[host] => x86_64-pc-linux-gnu
[ssl_version] => OpenSSL/1.0.2u
[libz_version] => 1.2.8
[protocols] => Array
(
[0] => dict
[1] => file
[2] => ftp
[3] => ftps
[4] => gopher
[5] => http
[6] => https
[7] => imap
[8] => imaps
[9] => ldap
[10] => ldaps
[11] => pop3
[12] => pop3s
[13] => rtmp
[14] => rtsp
[15] => scp
[16] => sftp
[17] => smb
[18] => smbs
[19] => smtp
[20] => smtps
[21] => telnet
[22] => tftp
)

)

Предопределённые константы

Эти константы определены данным расширением и будут доступны только в том
случае, если либо вкомпилированы в РНР, либо динамически загружены на этапе прогона.

CURLOPT_PORT (integer)
CURLOPT_FILE (integer)
CURLOPT_INFILE (integer)
CURLOPT_INFILESIZE (integer)
CURLOPT_URL (integer)
CURLOPT_PROXY (integer)
CURLOPT_VERBOSE (integer)
CURLOPT_HEADER (integer)
CURLOPT_HTTPHEADER (integer)
CURLOPT_NOPROGRESS (integer)
CURLOPT_NOBODY (integer)
CURLOPT_FAILONERROR (integer)
CURLOPT_UPLOAD (integer)
CURLOPT_POST (integer)
CURLOPT_FTPLISTONLY (integer)
CURLOPT_FTPAPPEND (integer)
CURLOPT_NETRC (integer)
CURLOPT_FOLLOWLOCATION (integer)
CURLOPT_FTPASCII (integer)
CURLOPT_PUT (integer)
CURLOPT_MUTE (integer)
CURLOPT_USERPWD (integer)
CURLOPT_PROXYUSERPWD (integer)
CURLOPT_RANGE (integer)
CURLOPT_TIMEOUT (integer)
CURLOPT_POSTFIELDS (integer)
CURLOPT_REFERER (integer)
CURLOPT_USERAGENT (integer)
CURLOPT_FTPPORT (integer)
CURLOPT_LOW_SPEED_LIMIT (integer)
CURLOPT_LOW_SPEED_TIME (integer)
CURLOPT_RESUME_FROM (integer)
CURLOPT_COOKIE (integer)
CURLOPT_SSLCERT (integer)
CURLOPT_SSLCERTPASSWD (integer)
CURLOPT_WRITEHEADER (integer)
CURLOPT_SSL_VERIFYHOST (integer)
CURLOPT_COOKIEFILE (integer)
CURLOPT_SSLVERSION (integer)
CURLOPT_TIMECONDITION (integer)
CURLOPT_TIMEVALUE (integer)
CURLOPT_CUSTOMREQUEST (integer)
CURLOPT_STDERR (integer)
CURLOPT_TRANSFERTEXT (integer)
CURLOPT_RETURNTRANSFER (integer)
CURLOPT_QUOTE (integer)
CURLOPT_POSTQUOTE (integer)
CURLOPT_INTERFACE (integer)
CURLOPT_KRB4LEVEL (integer)
CURLOPT_HTTPPROXYTUNNEL (integer)
CURLOPT_FILETIME (integer)
CURLOPT_WRITEFUNCTION (integer)
CURLOPT_READFUNCTION (integer)
CURLOPT_PASSWDFUNCTION (integer)
CURLOPT_HEADERFUNCTION (integer)
CURLOPT_MAXREDIRS (integer)
CURLOPT_MAXCONNECTS (integer)
CURLOPT_CLOSEPOLICY (integer)
CURLOPT_FRESH_CONNECT (integer)
CURLOPT_FORBID_REUSE (integer)
CURLOPT_RANDOM_FILE (integer)
CURLOPT_EGDSOCKET (integer)
CURLOPT_CONNECTTIMEOUT (integer)
CURLOPT_SSL_VERIFYPEER (integer)
CURLOPT_CAINFO (integer)
CURLOPT_COOKIEJAR (integer)
CURLOPT_SSL_CIPHER_LIST (integer)
CURLOPT_BINARYTRANSFER (integer)
CURLCLOSEPOLICY_LEAST_RECENTLY_USED (integer)
CURLCLOSEPOLICY_LEAST_TRAFFIC (integer)
CURLCLOSEPOLICY_SLOWEST (integer)
CURLCLOSEPOLICY_CALLBACK (integer)
CURLCLOSEPOLICY_OLDEST (integer)
CURLINFO_EFFECTIVE_URL (integer)
CURLINFO_HTTP_CODE (integer)
CURLINFO_HEADER_SIZE (integer)
CURLINFO_REQUEST_SIZE (integer)
CURLINFO_TOTAL_TIME (integer)
CURLINFO_NAMELOOKUP_TIME (integer)
CURLINFO_CONNECT_TIME (integer)
CURLINFO_PRETRANSFER_TIME (integer)
CURLINFO_SIZE_UPLOAD (integer)
CURLINFO_SIZE_DOWNLOAD (integer)
CURLINFO_SPEED_DOWNLOAD (integer)
CURLINFO_SPEED_UPLOAD (integer)
CURLINFO_FILETIME (integer)
CURLINFO_SSL_VERIFYRESULT (integer)
CURLINFO_CONTENT_LENGTH_DOWNLOAD (integer)
CURLINFO_CONTENT_LENGTH_UPLOAD (integer)
CURLE_OK (integer)
CURLE_UNSUPPORTED_PROTOCOL (integer)
CURLE_FAILED_INIT (integer)
CURLE_URL_MALFORMAT (integer)
CURLE_URL_MALFORMAT_USER (integer)
CURLE_COULDNT_RESOLVE_PROXY (integer)
CURLE_COULDNT_RESOLVE_HOST (integer)
CURLE_COULDNT_CONNECT (integer)
CURLE_FTP_WEIRD_SERVER_REPLY (integer)
CURLE_FTP_ACCESS_DENIED (integer)
CURLE_FTP_USER_PASSWORD_INCORRECT (integer)
CURLE_FTP_WEIRD_PASS_REPLY (integer)
CURLE_FTP_WEIRD_USER_REPLY (integer)
CURLE_FTP_WEIRD_PASV_REPLY (integer)
CURLE_FTP_WEIRD_227_FORMAT (integer)
CURLE_FTP_CANT_GET_HOST (integer)
CURLE_FTP_CANT_RECONNECT (integer)
CURLE_FTP_COULDNT_SET_BINARY (integer)
CURLE_PARTIAL_FILE (integer)
CURLE_FTP_COULDNT_RETR_FILE (integer)
CURLE_FTP_WRITE_ERROR (integer)
CURLE_FTP_QUOTE_ERROR (integer)
CURLE_HTTP_NOT_FOUND (integer)
CURLE_WRITE_ERROR (integer)
CURLE_MALFORMAT_USER (integer)
CURLE_FTP_COULDNT_STOR_FILE (integer)
CURLE_READ_ERROR (integer)
CURLE_OUT_OF_MEMORY (integer)
CURLE_OPERATION_TIMEOUTED (integer)
CURLE_FTP_COULDNT_SET_ASCII (integer)
CURLE_FTP_PORT_FAILED (integer)
CURLE_FTP_COULDNT_USE_REST (integer)
CURLE_FTP_COULDNT_GET_SIZE (integer)
CURLE_HTTP_RANGE_ERROR (integer)
CURLE_HTTP_POST_ERROR (integer)
CURLE_SSL_CONNECT_ERROR (integer)
CURLE_FTP_BAD_DOWNLOAD_RESUME (integer)
CURLE_FILE_COULDNT_READ_FILE (integer)
CURLE_LDAP_CANNOT_BIND (integer)
CURLE_LDAP_SEARCH_FAILED (integer)
CURLE_LIBRARY_NOT_FOUND (integer)
CURLE_FUNCTION_NOT_FOUND (integer)
CURLE_ABORTED_BY_CALLBACK (integer)
CURLE_BAD_FUNCTION_ARGUMENT (integer)
CURLE_BAD_CALLING_ORDER (integer)
CURLE_HTTP_PORT_FAILED (integer)
CURLE_BAD_PASSWORD_ENTERED (integer)
CURLE_TOO_MANY_REDIRECTS (integer)
CURLE_UNKNOWN_TELNET_OPTION (integer)
CURLE_TELNET_OPTION_SYNTAX (integer)
CURLE_OBSOLETE (integer)
CURLE_SSL_PEER_CERTIFICATE (integer)

Примеры

После того как вы скомпилировали PHP с поддержкой CURL, вы можете начать
использовать curl-функций. Основная идея функций CURL — вы инициализируете CURL-сессию
с использованием curl_init(), затем можно установить все ваши опции для трансфера через использование
curl_exec(), а затем закрыть сессию функцией curl_close().

Пример 1. Инициализация новой сессии CURL и получение web-страницы.
<?php
$ch = curl_init();

curl_setopt ($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt ($ch, CURLOPT_HEADER, 0);

curl_exec ($ch);

curl_close ($ch);
?>
Пример 2. Использование модуля CURL РНР для получения example.com
<?php
$ch = curl_init ("http://www.example.com/");
$fp = fopen ("example_homepage.txt", "w");

curl_setopt ($ch, CURLOPT_FILE, $fp);
curl_setopt ($ch, CURLOPT_HEADER, 0);

curl_exec ($ch);
curl_close ($ch);
fclose ($fp);
?>

Пример 3. Проверка доступности URL с помощью CURL РНР
<?php
function check_url($url) {
    $c = curl_init();
    curl_setopt($c, CURLOPT_URL, $url);
    curl_setopt($c, CURLOPT_HEADER, 1); // читать заголовок
    curl_setopt($c, CURLOPT_NOBODY, 1); // читать ТОЛЬКО заголовок без тела
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // не использовать cache
    if (!curl_exec($c)) return false;

    $httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
    return ($httpcode < 400);
}
?>

Пример 4. Отделение заголовка от тела, полученного с помощью CURL РНР
<?php
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($output, 0, $header_size - 4);
$body = substr($output, $header_size);
?>

Пример 5. Определение адреса перехода URL с помощью CURL РНР

the problem: curl_setopt($ch,FOLLOW_LOCATION,1);
the error: trouble with open_basedir and safe_mode
the solution: a function already developed by someone
the solution n 2: the same function, modifed, works great for me..

<?php
    function curl_redir_exec($ch)
    {
        static $curl_loops = 0;
        static $curl_max_loops = 20;
        if ($curl_loops++ >= $curl_max_loops)
        {
            $curl_loops = 0;
            return FALSE;
        }
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        list($header, $data) = explode("nn", $data, 2);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($http_code == 301 || $http_code == 302)
        {
            $matches = [];
            preg_match('/Location:(.*?)n/', $header, $matches);
            $url = @parse_url(trim(array_pop($matches)));
            if (!$url)
            {
                //couldn't process the url to redirect to
                $curl_loops = 0;
                return $data;
            }
            $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
            if (!$url['scheme'])
                $url['scheme'] = $last_url['scheme'];
            if (!$url['host'])
                $url['host'] = $last_url['host'];
            if (!$url['path'])
                $url['path'] = $last_url['path'];
            $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');
            curl_setopt($ch, CURLOPT_URL, $new_url);
            debug('Redirecting to', $new_url);
            return curl_redir_exec($ch);
        } else {
            $curl_loops=0;
            return $data;
        }
    }
?>

just use this function without de FOLLOW_LOCATION and should work. the problem was that when you get to the line where you return the data if http_code was different than 301 oe 302, $data has obsolete information or none. so $debbbb does the job.

Пример 6. Разбор cookie из заголовка с помощью CURL РНР

Sometimes you can’t use CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE becoz of the server
php-settings(They say u may grab any files from server using these options). Here is the solution
1)Don’t use CURLOPT_FOLLOWLOCATION
2)Use curl_setopt($ch, CURLOPT_HEADER, 1)
3)Grab from the header cookies like this:

preg_match_all('|Set-Cookie: (.*);|U', $content, $results);
$cookies = implode(';', $results[1]);

4)Set them using curl_setopt($ch, CURLOPT_COOKIE, $cookies);

Пример 7. Разбор cookie из заголовка с помощью CURL РНР

As Yevgen mentioned earlier sometimes we can’t use CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE. Below is a header callback function I wrote back in
January that lets you maintain cookies between cURL requests. Cookies are added to $ch during all requests even during redirection,
so you can use it together with CURLOPT_FOLLOWLOCATION.
Here is the code:

function read_header($ch, $string)
{
global $location; #keep track of location/redirects
global $cookiearr; #store cookies here
global $ch;
# ^overrides the function param $ch
# this is okay because we need to
# update the global $ch with
# new cookies

$length = strlen($string);
if(!strncmp($string, "Location:", 9))
{ #keep track of last redirect
$location = trim(substr($string, 9, -1));
}
if(!strncmp($string, "Set-Cookie:", 11))
{ #get the cookie
    $cookiestr = trim(substr($string, 11, -1));
    $cookie = explode(';', $cookiestr);
    $cookie = explode('=', $cookie[0]);
    $cookiename = trim(array_shift($cookie));
    $cookiearr[$cookiename] = trim(implode('=', $cookie));
    }
    $cookie = "";
    if(trim($string) == "")
    {  #execute only at end of header
        foreach ($cookiearr as $key=>$value)
        {
            $cookie .= "$key=$value; ";
        }
        curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    }

    return $length;
}
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');

This code assumes that you will reuse $ch without initializing it every time (call curl_init only once, in the beginning).
If you need to initialize $ch again at any point in your code you can access the currently stored cookies in $cookiearr and include them in the new $ch.

I wrote this function before I had enough experience with regular expressions so you won’t find any preg_match calls here.
I have used this code for quite a while and without any problems accessing gmail, yahoo, hotmail, aol etc.
where I had to go through login and a few pages before getting to what I was looking for.

Пример 8. Установка обработчика загрузки заголовка с помощью CURL РНР

Using cURL, I needed to call a third-party script which was returning binary data as attachment to pass on retrieved data again as attachment.

Problem was that the third-party script occassionally returned HTTP errors and I wanted to avoid passing on zero-length attachment in such case.

Combination of using CURLOPT_FAILONERROR and CURLOPT_HEADERFUNCTION callback helped to process the third-party script HTTP errors neatly:

function curlHeaderCallback($resURL, $strHeader) {
    if (preg_match('/^HTTP/i', $strHeader)) {
        header($strHeader);
        header('Content-Disposition: attachment; filename="file-name.zip"');
    }
    return strlen($strHeader);
}

$resURL = curl_init('http://htmlweb.ru/');
curl_setopt($resURL, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resURL, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');
curl_setopt($resURL, CURLOPT_FAILONERROR, 1);
curl_exec ($resURL);

$intReturnCode = curl_getinfo($resURL, CURLINFO_HTTP_CODE);
curl_close ($resURL);

if ($intReturnCode != 200) {
    print 'Ошибка с кодом: ' . $intReturnCode;
}
Пример 9. Сохранение страницы в файл с подсчетом скорости передачи с помощью CURL РНР
WritePageToFile( 'http://es.php.net', 'es.php.net.txt' );

function WritePageToFile( $sHTMLpage, $sTxtfile ) {
    $sh =          curl_init( $sHTMLpage );
    $hFile =       FOpen( $sTxtfile, 'w' );
    curl_setopt( $sh, CURLOPT_FILE, $hFile );
    curl_setopt( $sh, CURLOPT_HEADER, 0 );
    curl_exec  ( $sh );
    $sAverageSpeedDownload = curl_getInfo( $sh, CURLINFO_SPEED_DOWNLOAD );
    $sAverageSpeedUpload   = curl_getInfo( $sh, CURLINFO_SPEED_UPLOAD );
    echo '<pre>';
    echo 'Average speed download == ' . $sAverageSpeedDownload . '<br>';
    echo 'Average Speed upload    == ' . $sAverageSpeedUpload   . '<br>';
    echo '<br>';
    $aCURLinfo = curl_getInfo( $sh );
    print_r( $aCURLinfo );
    echo '</pre>';
    curl_close(  $sh );
    FClose    (  $hFile );
    echo '(<b>See the file  "'.$sTxtfile.'"  in the same path of the hosting'.
        ' to where this script PHP</b>).<br>';
}
Пример 9. Получение страницы через SSL соединение (https)
$ch=curl_init('https://htmlweb.ru');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Отключить ошибку "SSL certificate problem, verify that the CA cert is OK"
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// Отключить ошибку "SSL: certificate subject name 'hostname.ru' does not match target host name '123.123'"
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$out=curl_exec($ch);
    //$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    //echo "http_code=".$http_code,', err='.curl_error($ch);
curl_close($ch);
Пример 10. Использование сессий и cookie в curl
$cookie_filename=sys_get_temp_dir()+'/cookie.tmp';
$curl=curl_init('http://htmlweb.ru');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_filename);//сохранять полученные COOKIE в файл
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_filename); //отсылаем серверу COOKIE полученные от него при авторизации
$out=curl_exec($curl);
Пример 11. Отправка файла и многомерный массив в Curl. CURLOPT_POSTFIELDS + CurlFile

Если Вам нужно будет отправить в POST запросе многомерный массив и файл, то вы столкнетесь с неразрешимой проблемой.
Если передавать в CURLOPT_POSTFIELDS многомерный массив, то второй уровень будет передан как строка «Array».
Если преобразовать с помощью http_build_query, то Вы не сможете передать файл.

Ниже представлена функция кодирования двумерного массива с подгрузкой файлов для Curl,
которая будет работать как в старых версиях PHP 5.3, PHP 5.4, так и в PHP 5.6

/** преобразует многомерный массив в одномерный, используйя сложные индексы и заменяет @ в префиксе на CurlFile для испрользоания в Curl
* @param $inputArray
* @param string $inputKey
* @return array
$requestVars = array(
'id' => array(1, 2,'id'=>1234),
'name' => 'log',
'logfile' => '@/tmp/test.log');
получим:
["id[0]"]=> int(1)
["id[1]"]=> int(2)
["id[id]"]=> int(1234)
["name"]=> string(3) "log"
["logfile"]=> string(13) "/tmp/test.log" }
*/
function convertToStringArray($inputArray, $inputKey='') {
 $resultArray=[];
 foreach ($inputArray as $key => $value) {
  $tmpKey = (bool)$inputKey ? $inputKey."[$key]" : $key;
  if (is_array($value)) {
    $resultArray+=convertToStringArray($value, $tmpKey);
   } elseif ($value[0] == '@'){
    $resultArray[$tmpKey] = (class_exists(' CURLFile ', false)) ? new CurlFile(ltrim($value, '@')) : $value;
   } else {
    $resultArray[$tmpKey] = $value;
   }
  }
 return $resultArray;
}
// проверяем
$requestVars = array(
'id' => array(1, 2,'id'=>1234),
'name' => 'log',
'logfile' => '@/tmp/test.log');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'htmlweb.ru');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, convertToStringArray($requestVars));
$res = curl_exec($ch);
curl_close($ch);

Прикладные примеры использования Curl

Читать дальше: htaccess и PHP

5 PHP cURL examples

Published September 06, 2015

Working on the server side does not necessarily imply that all the required information needs to be present on the database of the site on which we are working. As a matter of fact, growing parts of the information that is used on the server side comes from external sources, often via an API that allows some kind of service to provide information to the website without having access to the database on the remote site. To utilize this information, we can use the cURL built-in PHP extension.

cURL is a PHP extension, that allows us to receive and send information via the URL syntax. By doing so, cURL makes it easy to communicate between different websites and domains. This tutorial includes 5 common cases for the use of cURL, and they include:

Joseph Benharosh web developer

# How does the cURL extension work?

cURL works by sending a request to a web site, and this process includes the following four parts:

1. Initialization.

$handle = curl_init();

2. Setting the options. There are many options, for example, an option that defines the URL.

curl_setopt($handle, CURLOPT_URL, $url);

3. Execution with curl_exec().

$data = curl_exec($handle);

4. Releasing the cURL handle.

curl_close($handle);

The second part is the most interesting because it allows us to define how cURL works in a highly accurate manner, by using the many options it has to offer.

# 1. How to download the contents of a remote website to a local file?

In order to download the contents of a remote web site, we need to define the following options:

CURLOPT_URL— Defines the remote URL.

CURLOPT_RETURNTRANSFER— Enables the assignment of the data that we download from the remote site to a variable. In this example, we assign the data into the variable $output.

<?php
$handle = curl_init();
 
$url = "https://www.ladygaga.com";
 
// Set the url
curl_setopt($handle, CURLOPT_URL, $url);
// Set the result output to be a string.
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
 
$output = curl_exec($handle);
 
curl_close($handle);
 
echo $output;

When we print the value of the variable $output to the screen, we will see the local version of the web site for the world’s best singer.

Example to the content of the website that we download

The options can be written more compactly using curl_setopt_array(), which is a cURL function that convenes the options into an array.

curl_setopt_array($handle,
  array(
      CURLOPT_URL            => $url,
      CURLOPT_RETURNTRANSFER => true
  )
);

# 2. How to download a file from a remote site using cURL?

A remote file can be downloaded to our server, if the option CURLOPT_ FILE is set. For example, the following code downloads the book «The Divine Comedy» from Project Gutenberg into a the_divine_comedy.html file on our server:

<?php
// The distant site url.
$url = "https://www.gutenberg.org/files/46852/46852-h/46852-h.htm";
// The file on our server.
$file = __DIR__ . DIRECTORY_SEPARATOR . "the_divine_comedy.html";
$handle = curl_init();
 
// Open the file on our server for writing.
$fileHandle = fopen($file, "w");
 
curl_setopt_array($handle,
  array(
     CURLOPT_URL           => $url,
      CURLOPT_FILE => $fileHandle,
  )
);
 
$data = curl_exec($handle);
 
curl_close($handle);
 
fclose($fileHandle);

# Handling the returned response

In order to get the parameters of the response for it to be monitored and debugged, we need to set the option CURLOPT_HEADER. For example:

<?php
$url = ""https://www.gutenberg.org/files/41537/41537-h/41537-h.htm";
 
$file = __DIR__ . DIRECTORY_SEPARATOR . "the_divine_comedy.html";
 
$handle = curl_init();
 
$fileHandle = fopen($file, "w");
 
curl_setopt_array($handle,
  array(
    CURLOPT_URL => $url,
    CURLOPT_FILE  => $fileHandle,
    CURLOPT_HEADER => true
  )
);
 
$data = curl_exec($handle);

To get additional information about the request, we use the curl_getinfo command that enables us to receive important technical information about the response, including the status code (200 for success) and the size of the downloaded file.

$responseCode   = 
    curl_getinfo($handle, 
        CURLINFO_HTTP_CODE
);
 
$downloadLength = 
    curl_getinfo($handle, 
         CURLINFO_CONTENT_LENGTH_DOWNLOAD
);

In addition, we can also use the commands: curl_error and curl_errno to debug the response and receive informative error messages.

if(curl_errno($handle))
{
  print curl_error($handle);
}

Let’s see the full code:

<?php
$url = "https://www.gutenberg.org/files/46852/46852-h/46852-h.htm";
 
$file = __DIR__ . DIRECTORY_SEPARATOR . "the_divine_comedy.html";
 
$handle = curl_init();
 
$fileHandle = fopen($file, "w");
 
curl_setopt_array($handle,
  array(
    CURLOPT_URL    => $url,
    CURLOPT_FILE   => $fileHandle,
    CURLOPT_HEADER => true
  )
);
 
$data = curl_exec($handle);
 
$responseCode   = curl_getinfo($handle, CURLINFO_HTTP_CODE);
 
$downloadLength = curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
 
if(curl_errno($handle))
{
  print curl_error($handle);
}
else
{
  if($responseCode == "200") echo "successful request";
    
  echo " # download length : " . $downloadLength;
 
  curl_close($handle);
 
  fclose($fileHandle);
}

# 3. How to submit forms with cURL?

Until this moment, we have demonstrated the use of the GET method of HTTP (which is generally used to watch and download content). cURL can also make use of the POST method of HTTP in order to submit forms.

In order to demonstrate form submission with cURL, we need to create the following two files:

  1. index.php in which we put the cURL script.
  2. form.php in which we put the form to be submitted.

The form.php will be in reality, found on a remote server (although, for the sake of the example, both files may be placed on the same server). Also, for the example, we will use a form with 3 fields: firstName, lastName and submit.

<?php
if(isset($_POST["submit"]))
{
  echo "Full name is " . $_POST["firstName"] .
     "  " . $_POST["lastName"];
  exit;
}
?>
 
<html>
<body>
 
<form method = "POST" action = "" >
  <input  name="firstName"  type="text"> 
  <input  name="lastName"  type="text">
  <input  type="submit"  name="submit"  value="שלח" >
</form>
</body>
</html>

To submit the form, the following options need to be set:

  1. CURLOPT_POST– Sets the request to be in a post mode.
  2. CURLOPT_POSTFIELDS— Receives the associative array of the fields that we want to post. The array keys are named after the name of the form fields.
<?php
$handle = curl_init();
 
$url = "https://localhost/curl/theForm.php";
 
// Array with the fields names and values.
// The field names should match the field names in the form.
 
$postData = array(
  'firstName' => 'Lady',
  'lastName'  => 'Gaga',
  'submit'    => 'ok'
);
 
curl_setopt_array($handle,
  array(
     CURLOPT_URL => $url,
     // Enable the post response.
    CURLOPT_POST       => true,
    // The data to transfer with the response.
    CURLOPT_POSTFIELDS => $postData,
    CURLOPT_RETURNTRANSFER     => true,
  )
);
 
$data = curl_exec($handle);
 
curl_close($handle);
 
echo $data;

# 4. How to perform basic HTTP authentication with cURL?

In order to authenticate with cURL, the following 3 options need to be set:

  1. CURLOPT_HTTPAUTH
  2. CURLOPT_USERPWD– Through which we define the username and password.
  3. CURLOPT_RETURNTRANSFER

Let’s see the code:

curl_setopt_array($handle,
  array(
    CURLOPT_URL => $url,
   CURLOPT_HTTPAUTH => CURLAUTH_ANY,
   CURLOPT_USERPWD  => "$username:$password",
   CURLOPT_RETURNTRANSFER   => true,
  )
);

# 5. How to handle cookies with cURL?

The use of cookies allows a website to identify returning visitors and authenticated users. To this end, cURL provides us with a mechanism through which we can save cookies.

The two main options that allow us to handle cookies are:

  1. CURLOPT_COOKIEJAR– Defines the file required to write the cookies.
  2. CURLOPT_COOKIEFILE– Defines the file from which the cookies are to be read.

The following code example writes the cookies into a cookie.txt file on the first visit, and then reads the data in later visits.

<?php
 
$handle = curl_init();
 
$url = "https://www.ladygaga.com/artrave-the-artpop-ball";
 
$file = __DIR__ . DIRECTORY_SEPARATOR . "cookie.txt";
 
curl_setopt_array($handle,
  array(
    CURLOPT_URL => $url,
     // The file to which the cookies need to be written.
    CURLOPT_COOKIEFILE => $file,
    // The file freom which the cookies need to be read.
    CURLOPT_COOKIEJAR  => $file,
    CURLOPT_RETURNTRANSFER     => true,
  )
);
 
$data = curl_exec($handle);
 
curl_close($handle);

Conclusion

Using PHP’s cURL extension provides us with a convenient way to communicate with other web sites, particularly with APIs that are provided by a third party. In the next tutorial, we will learn how to request for private details in the name of users that sign in to our website with their GitHub account. It will be done by using Github’s API, and with the help of cURL. The tutorial will be a good starting point for learning how to make a social login with any social network.

cURL – это специальный инструмент, который предназначен для того, чтобы передавать файлы и данные синтаксисом URL. Данная технология поддерживает множество протоколов, таких как HTTP, FTP, TELNET и многие другие. Изначально cURL было разработано для того, чтобы быть инструментом командной строки. К счастью для нас, библиотека cURL поддерживается языком программирования PHP. В этой статье мы рассмотрим некоторые расширенные функций cURL, а также затронем практическое применение полученных знаний средствами PHP.

Почему cURL?

На самом деле, существует немало альтернативных способов выборки содержания веб-страницы. Во многих случаях, главным образом из-за лени, я использовал простые PHP функции вместо cURL:

$content = file_get_contents("http://www.nettuts.com");
// или
$lines = file("http://www.nettuts.com");
// или
readfile("http://www.nettuts.com");

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

cURL — это мощная библиотека, которая поддерживает множество различных протоколов, опций и обеспечивает подробную информацию о URL запросах.

Базовая структура

Прежде чем мы двинемся дальше к более сложным примерам, давайте рассмотрим базовую структуру cURL запроса в PHP. Существует четыре основных шага, которые нужно учитывать в каждом скрипте:

  • Инициализация
  • Назначение параметров
  • Выполнение и выборка результата
  • Освобождение памяти
// 1. инициализация
$ch = curl_init();

// 2. указываем параметры, включая url
curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);

// 3. получаем HTML в качестве результата
$output = curl_exec($ch);

// 4. закрываем соединение
curl_close($ch);

Шаг #2 (то есть, вызов curl_setopt()) будем обсуждать в этой статье намного больше, чем все другие этапы, т.к. на этой стадии происходит всё самое интересное и полезное, что вам необходимо знать. В cURL существует огромное количество различных опций, которые должны быть указаны, для того чтобы иметь возможность сконфигурировать URL-запрос самым тщательным образом. Мы не будем рассматривать весь список целиком, а остановимся только на том, что я посчитаю нужным и полезным для этого урока. Всё остальное вы сможете изучить сами, если эта тема вас заинтересует.

Проверка Ошибки

Вдобавок, вы также можете использовать условные операторы для проверки выполнения операции на успех:

// ...

$output = curl_exec($ch);

if ($output === FALSE) {

    echo "cURL Error: " . curl_error($ch);

}

// ...

Тут прошу отметить для себя очень важный момент: мы должны использовать “=== false” для сравнения, вместо “== false”. Для тех, кто не в курсе, это поможет нам отличать пустой результат от булевого значения false, которое и будет указывать на ошибку.

Получение информации

Ещё одним дополнительным шагом является получение данных о cURL запросе, после того, как он был выполнен.

// ...

curl_exec($ch);

$info = curl_getinfo($ch);

echo 'Took ' . $info['total_time'] . ' seconds for url ' . $info['url'];

// …

Возвращаемый массив содержит следующую информацию:

  • “url”
  • “content_type”
  • “http_code”
  • “header_size”
  • “request_size”
  • “filetime”
  • “ssl_verify_result”
  • “redirect_count”
  • “total_time”
  • “namelookup_time”
  • “connect_time”
  • “pretransfer_time”
  • “size_upload”
  • “size_download”
  • “speed_download”
  • “speed_upload”
  • “download_content_length”
  • “upload_content_length”
  • “starttransfer_time”
  • “redirect_time”

Обнаружение перенаправления в зависимости от браузера

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

Мы собираемся использовать опцию CURLOPT_HTTPHEADER для того, чтобы определить наши исходящие HTTP заголовки, включая название браузера пользователя и доступные языки. В конечном итоге мы сможем определить, какие сайты перенаправляют нас к разным URL.

// тестируем URL
$urls = array(
    "http://www.cnn.com",
    "http://www.mozilla.com",
    "http://www.facebook.com"
);
// тестируем браузеры
$browsers = array(

    "standard" => array (
     "user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)",
     "language" => "en-us,en;q=0.5"
     ),

    "iphone" => array (
     "user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3",
     "language" => "en"
     ),

    "french" => array (
     "user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)",
     "language" => "fr,fr-FR;q=0.5"
     )

);

foreach ($urls as $url) {

    echo "URL: $urln";

    foreach ($browsers as $test_name => $browser) {

     $ch = curl_init();

     // указываем url
     curl_setopt($ch, CURLOPT_URL, $url);

     // указываем заголовки для браузера
     curl_setopt($ch, CURLOPT_HTTPHEADER, array(
             "User-Agent: {$browser['user_agent']}",
             "Accept-Language: {$browser['language']}"
         ));

     // нам не нужно содержание страницы
     curl_setopt($ch, CURLOPT_NOBODY, 1);

     // нам необходимо получить HTTP заголовки
     curl_setopt($ch, CURLOPT_HEADER, 1);

     // возвращаем результаты вместо вывода
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

     $output = curl_exec($ch);

     curl_close($ch);

     // был ли HTTP редирект?
     if (preg_match("!Location: (.*)!", $output, $matches)) {

         echo "$test_name: redirects to $matches[1]n";

     } else {

         echo "$test_name: no redirectionn";

     }

    }
    echo "nn";
}

Сначала мы указываем список URL сайтов, которые будем проверять. Точнее, нам понадобятся адреса данных сайтов. Далее нам необходимо определить настройки браузера, чтобы протестировать каждый из этих URL. После этого мы воспользуемся циклом, в котором пробежимся по всем полученным результатам.

Приём, который мы используем в этом примере для того, чтобы задать настройки cURL, позволит нам получить не содержание страницы, а только HTTP-заголовки (сохраненные в $output). Далее, воспользовавшись простым regex, мы можем определить, присутствовала ли строка “Location:” в полученных заголовках.

Когда вы запустите данный код, то должны будете получить примерно следующий результат:

Создание POST запроса на определённый URL

При формировании GET запроса передаваемые данные могут быть переданы на URL через “строку запроса”. Например, когда Вы делаете поиск в Google, критерий поиска располагаются в адресной строке нового URL:

http://www.google.com/search?q=ruseller

Для того чтобы сымитировать данный запрос, вам не нужно пользоваться средствами cURL. Если лень вас одолевает окончательно, воспользуйтесь функцией “file_get_contents()”, для того чтобы получить результат.

Но дело в том, что некоторые HTML-формы отправляют POST запросы. Данные этих форм транспортируются через тело HTTP запроса, а не как в предыдущем случае. Например, если вы заполнили форму на форуме и нажали на кнопку поиска, то скорее всего будет совершён POST запрос:

http://codeigniter.com/forums/do_search/

Мы можем написать PHP скрипт, который может сымитировать этот вид URL запроса. Сначала давайте создадим простой файл для принятия и отображения POST данных. Назовём его post_output.php:

Затем мы создаем PHP скрипт, чтобы выполнить cURL запрос:

$url = "http://localhost/post_output.php";

$post_data = array (
    "foo" => "bar",
    "query" => "Nettuts",
    "action" => "Submit"
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// указываем, что у нас POST запрос
curl_setopt($ch, CURLOPT_POST, 1);
// добавляем переменные
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

$output = curl_exec($ch);

curl_close($ch);

echo $output;

При запуске данного скрипта вы должны получить подобный результат:

Таким образом, POST запрос был отправлен скрипту post_output.php, который в свою очередь, вывел суперглобальный массив $_POST, содержание которого мы получили при помощи cURL.

Загрузка файла

Загрузка файла будет выглядеть практически так же, как и обычный POST запрос, так как все формы загрузки файла работают только с ним.

Сначала давайте создадим файл для того, чтобы сформировать его и отправить файлу upload_output.php:

А вот и код скрипта, который выполняет указанный выше функционал:

$url = "http://localhost/upload_output.php";

$post_data = array (
    "foo" => "bar",
    // файл, который необходимо загрузить
    "upload" => "@C:/wamp/www/test.zip"
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

$output = curl_exec($ch);

curl_close($ch);

echo $output;

Когда вы хотите загрузить файл, все, что вам нужно сделать, так это передать его как обычную post переменную, предварительно поместив перед ней символ @. При запуске написанного скрипта вы получите следующий результат:

Множественный cURL

Одной из самых сильных сторон cURL является возможность создания «множественных» cURL обработчиков. Это позволяет вам открывать соединение к множеству URL одновременно и асинхронно.

В классическом варианте cURL запроса выполнение скрипта приостанавливается, и происходит ожидание завершения операции URL запроса, после чего работа скрипта может продолжиться. Если вы намереваетесь взаимодействовать с целым множеством URL, это приведёт к довольно-таки значительным затратам времени, поскольку в классическом варианте вы можете работать только с одним URL за один раз. Однако, мы можем исправить данную ситуацию, воспользовавшись специальными обработчиками.

Давайте рассмотрим пример кода, который я взял с php.net:

// создаём несколько cURL ресурсов
$ch1 = curl_init();
$ch2 = curl_init();

// указываем URL и другие параметры
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);

//создаём множественный cURL обработчик
$mh = curl_multi_init();

//добавляем несколько обработчиков
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$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);
    }
}

//закрытие
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

Идея состоит в том, что вы можете использовать множественные cURL обработчики. Используя простой цикл, вы можете отследить, какие запросы ещё не выполнились.

В этом примере есть два основных цикла. Первый цикл do-while вызывает функцию curl_multi_exec(). Эта функция не блокируемая. Она выполняется с той скоростью, с которой может, и возвращает состояние запроса. Пока возвращенное значение является константой ‘CURLM_CALL_MULTI_PERFORM’, это означает, что работа ещё не завершена (например, в данный момент происходит отправка http заголовков в URL); Именно поэтому мы продолжаем проверять это возвращаемое значение, пока не получим другой результат.

В следующем цикле мы проверяем условие, пока переменная $active = ‘true’. Она является вторым параметром для функции curl_multi_exec(). Значение данной переменной будет равно ‘true’, до тех пор, пока какое-то из существующих изменений является активным. Далее мы вызываем функцию curl_multi_select(). Её выполнение ‘блокируется’, пока существует хоть одно активное соединение, до тех пор, пока не будет получен ответ. Когда это произойдёт, мы возвращаемся в основной цикл, чтобы продолжить выполнение запросов.

А теперь давайте применим полученные знания на примере, который будет реально полезным для большого количества людей.

Проверяем ссылки в WordPress

Представьте себе блог с огромным количеством постов и сообщений, в каждом из которых есть ссылки на внешние интернет ресурсы. Некоторые из этих ссылок по различным причинам могли бы уже быть «мертвыми». Возможно, страница была удалена или сайт вовсе не работает.

Мы собираемся создать скрипт, который проанализирует все ссылки и найдёт незагружающиеся веб-сайты и страницы 404, после чего предоставит нам подробнейший отчёт.

Сразу же скажу, что это не пример создания плагина для WordPress. Это всего на всего хороший полигон для наших испытаний.

Давайте же наконец начнём. Сначала мы должны сделать выборку всех ссылок из базы данных:

// конфигурация
$db_host = 'localhost';
$db_user = 'root';
$db_pass = '';
$db_name = 'wordpress';
$excluded_domains = array(
    'localhost', 'www.mydomain.com');
$max_connections = 10;
// инициализация переменных
$url_list = array();
$working_urls = array();
$dead_urls = array();
$not_found_urls = array();
$active = null;

// подключаемся к MySQL
if (!mysql_connect($db_host, $db_user, $db_pass)) {
    die('Could not connect: ' . mysql_error());
}
if (!mysql_select_db($db_name)) {
    die('Could not select db: ' . mysql_error());
}

// выбираем все опубликованные посты, где есть ссылки
$q = "SELECT post_content FROM wp_posts
    WHERE post_content LIKE '%href=%'
    AND post_status = 'publish'
    AND post_type = 'post'";
$r = mysql_query($q) or die(mysql_error());
while ($d = mysql_fetch_assoc($r)) {

    // делаем выборку ссылок при помощи регулярных выражений
    if (preg_match_all("!href="(.*?)"!", $d['post_content'], $matches)) {

     foreach ($matches[1] as $url) {

         $tmp = parse_url($url);
         if (in_array($tmp['host'], $excluded_domains)) {
             continue;
         }

         $url_list []= $url;
     }
    }
}

// убираем дубликаты
$url_list = array_values(array_unique($url_list));

if (!$url_list) {
    die('No URL to check');
}

Сначала мы формируем конфигурационные данные для взаимодействия с базой данных, далее пишем список доменов, которые не будут участвовать в проверке ($excluded_domains). Также мы определяем число, характеризующее количество максимальных одновременных соединений, которые мы будем использовать в нашем скрипте ($max_connections). Затем мы присоединяемся к базе данных, выбираем посты, которые содержат ссылки, и накапливаем их в массив ($url_list).

Следующий код немного сложен, так что разберитесь в нём от начала до конца:

// 1. множественный обработчик
$mh = curl_multi_init();

// 2. добавляем множество URL
for ($i = 0; $i < $max_connections; $i++) {
    add_url_to_multi_handle($mh, $url_list);
}

// 3. инициализация выполнения
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

// 4. основной цикл
while ($active && $mrc == CURLM_OK) {

    // 5. если всё прошло успешно
    if (curl_multi_select($mh) != -1) {

     // 6. делаем дело
     do {
         $mrc = curl_multi_exec($mh, $active);
     } while ($mrc == CURLM_CALL_MULTI_PERFORM);

     // 7. если есть инфа?
     if ($mhinfo = curl_multi_info_read($mh)) {
         // это значит, что запрос завершился

         // 8. извлекаем инфу
         $chinfo = curl_getinfo($mhinfo['handle']);

         // 9. мёртвая ссылка?
         if (!$chinfo['http_code']) {
             $dead_urls []= $chinfo['url'];

         // 10. 404?
         } else if ($chinfo['http_code'] == 404) {
             $not_found_urls []= $chinfo['url'];

         // 11. рабочая
         } else {
             $working_urls []= $chinfo['url'];
         }

         // 12. чистим за собой
         curl_multi_remove_handle($mh, $mhinfo['handle']); // в случае зацикливания, закомментируйте данный вызов 
         curl_close($mhinfo['handle']);

         // 13. добавляем новый url и продолжаем работу
         if (add_url_to_multi_handle($mh, $url_list)) {

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

// 14. завершение
curl_multi_close($mh);

echo "==Dead URLs==n";
echo implode("n",$dead_urls) . "nn";

echo "==404 URLs==n";
echo implode("n",$not_found_urls) . "nn";

echo "==Working URLs==n";
echo implode("n",$working_urls);

function add_url_to_multi_handle($mh, $url_list) {
    static $index = 0;

    // если у нас есть ещё url, которые нужно достать
    if ($url_list[$index]) {

     // новый curl обработчик
     $ch = curl_init();

     // указываем url
     curl_setopt($ch, CURLOPT_URL, $url_list[$index]);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
     curl_setopt($ch, CURLOPT_NOBODY, 1);

     curl_multi_add_handle($mh, $ch);

     // переходим на следующий url
     $index++;

     return true;
    } else {

     // добавление новых URL завершено
     return false;
    }
}

Тут я попытаюсь изложить всё по полочкам. Числа в списке соответствуют числам в комментарии.

  1. 1. Создаём множественный обработчик;
  2. 2. Функцию add_url_to_multi_handle() мы напишем чуть позже. Каждый раз, когда она будет вызываться, начнётся обработка нового url. Первоначально, мы добавляем 10 ($max_connections) URL;
  3. 3. Для того чтобы начать работу, мы должны запустить функцию curl_multi_exec(). До тех пор, пока она будет возвращать CURLM_CALL_MULTI_PERFORM, нам ещё есть, что делать. Это нам нужно, главным образом, для того, чтобы создать соединения;
  4. 4. Далее следует основной цикл, который будет выполняться до тех пор, пока у нас есть хоть одно активное соединение;
  5. 5. curl_multi_select() зависает в ожидании, пока поиск URL не завершится;
  6. 6. И снова мы должны заставить cURL выполнить некоторую работу, а именно, сделать выборку данных возвращаемого ответа;
  7. 7. Тут происходит проверка информации. В результате выполнения запроса будет возвращён массив;
  8. 8. В возвращенном массиве присутствует cURL обработчик. Его мы и будем использовать для того, чтобы выбрать информацию об отдельном cURL запросе;
  9. 9. Если ссылка была мертва, или время выполнения скрипта вышло, то нам не следует искать никакого http кода;
  10. 10. Если ссылка возвратила нам страницу 404, то http код будет содержать значение 404;
  11. 11. В противном случае, перед нами находится рабочая ссылка. (Вы можете добавить дополнительные проверки на код ошибки 500 и т.д…);
  12. 12. Далее мы удаляем cURL обработчик, потому что больше в нём не нуждаемся;
  13. 13. Теперь мы можем добавить другой url и запустить всё то, о чём говорили до этого;
  14. 14. На этом шаге скрипт завершает свою работу. Мы можем удалить всё, что нам не нужно и сформировать отчет;
  15. 15. В конце концов, напишем функцию, которая будет добавлять url в обработчик. Статическая переменная $index будет увеличиваться каждый раз, когда данная функция будет вызвана.

Я использовал данный скрипт на своем блоге (с некоторыми неработающими ссылками, которые добавил нарочно для того, чтобы протестировать его работу) и получил следующий результат:

В моём случае, скрипту потребовалось чуть меньше чем 2 секунды, чтобы пробежаться по 40 URL. Увеличение производительности является существенным при работе с еще большим количеством URL адресов. Если вы открываете десять соединений одновременно, то скрипт может выполниться в десять раз быстрее.

Пару слов о других полезных опциях cURL

HTTP Аутентификация

Если на URL адресе есть HTTP аутентификация, то вы без труда можете воспользоваться следующим скриптом:

$url = "http://www.somesite.com/members/";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// указываем имя и пароль
curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");

// если перенаправление разрешено 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// то сохраним наши данные в cURL
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);

$output = curl_exec($ch);

curl_close($ch);

FTP загрузка

В PHP также существует библиотека для работы с FTP, но вам ничего не мешает и тут воспользоваться средствами cURL:

// открываем файл
$file = fopen("/path/to/file", "r");

// в url должно быть следующее содержание
$url = "ftp://username:password@mydomain.com:21/path/to/new/file";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file"));

// указывам ASCII мод
curl_setopt($ch, CURLOPT_FTPASCII, 1);

$output = curl_exec($ch);
curl_close($ch);

Используем Прокси

Вы можете выполнить свой URL запрос через прокси:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,'http://www.example.com');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// указываем адрес
curl_setopt($ch, CURLOPT_PROXY, '11.11.11.11:8080');

// если необходимо предоставить имя пользователя и пароль
curl_setopt($ch, CURLOPT_PROXYUSERPWD,'user:pass');

$output = curl_exec($ch);

curl_close ($ch);

Функции обратного вызова

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

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,'http://net.tutsplus.com');

curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function");

curl_exec($ch);

curl_close ($ch);

function progress_function($ch,$str) {

    echo $str;
    return strlen($str);

}

Подобная функция ДОЛЖНА возвращать длину строки, что является обязательным требованием.

Заключение

Сегодня мы познакомились с тем, как можно применить библиотеку cURL в своих корыстных целях. Я надеюсь, что вам понравилась данная статья.

Спасибо! Удачного дня!

Понравилась статья? Поделить с друзьями:
  • Prison architect ошибка связи со steam
  • Print cancelled error
  • Prisma generate error
  • Print a message of the thrown exception to system error
  • Prism3d engine ошибка как исправить