cURL - это просто

cURL - это просто

Технология cURL

cURL - это технология, которая предназначена для передачи/получения данных посредстов URL. Технология cURL поддерживает такие распространенные протоколы, как HTTP, FTP, HTTPs и другие. Изначально cURL был инструментом командной строки, однако разработчики PHP не поленились и создали библиотеку в PHP, чем облегчили жизнь миллионам программистам. Давайте попробуем вместе разобраться с технологией cURL на примерах. Советую читать всё и по порядку.

Я знаю достаточно много примеров, где для получения сторонних web-страниц (парсеры) использовались совершенно другие способы, отличные от cURL. Например:

Почему разработчики использовали их и что в них не так? А потому, что не знали, либо не хотели знать, что такое cURL. А не так в них то, что функционал ограничен: получили страницу и все на этом, в то время, как cURL может отправить форму на странице, получить ответ, обработать ошибку, начать всё занова и т.д.

Принцип работы cURL

При использовании cURL-запросов существует 4 основных шага, которые должны (обязаны) быть в вашем скрипте, это:

Без любого из этих шагов ваш скрипт обречен на неудачу. Итак, основные шаги:


// 1. инициализация
$ch = curl_init();

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

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

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

Думаю что все шаги вам понятны за исключением второго: "Указания параметров". На этом шаге мы остановимся более подробно, т.к. именно он задает все необходимые настройки/параметры/методы.

Ошибки в ходе работы скрипта

Дабы не нагружать сервер дальнейшими вычеслениями, всегда проверяйте результат выполнения функции curl_exec:


$output = curl_exec($ch);
// А вдруг ошибочка?
if ($output === FALSE) {
  //Тут-то мы о ней и скажем
    echo "cURL Error: " . curl_error($ch);
  return;
}

Отмечу, что знак сравнения здесь '===', а не '==', т.е. сравнивается именно на наличие логического FALSE, а не пустой строки или строки 'false'.

Результат запроса

Ну а после того, как CURL-запрос был выполнен, неплохо бы было знать, что он вернул:


// Выполняем запрос
curl_exec($ch);
//Получаем информацию о запросе
$info = curl_getinfo($ch);
//Выводим какую-то инфомрацию
echo 'Запрос выполнился за  ' . $info['total_time'] . ' сек. к URL: ' . $info['url'];

А вот какие еще даные мы можем получить:

Индекс массива Значение Индекс массива Значение
url string(17) "http://intop24.ru" content_type string(24) "text/html; charset=utf-8"
http_code int(200) header_size int(218)
request_size int(49) filetime int(-1)
ssl_verify_result int(0) redirect_count int(0)
total_time float(0.009419) namelookup_time float(1.3E-5)
connect_time float(1.3E-5) pretransfer_time float(1.4E-5)
size_upload float(0) size_download float(46523)
speed_download float(4939271) speed_upload float(0)
download_content_length float(-1) upload_content_length float(0)
starttransfer_time float(0.009374) redirect_time float(0)
certinfo array(0) { } redirect_url string(0) ""

POST запрос с помощью CURL

Давайте напишем наш первый скрипт, который отправит данные методом POST на какую-нибудь страницу и посмотрит, что отобразилось на этой странице.

Сначала нам нужен файл, который бы принял наши данные и что-то вывел на страницу. Я расположил его по адресу http://intop24.ru/demo/curl/post.php. В нем содержится следующий код:


if (isset($_POST) && sizeof($_POST) > 0) {
  print_r($_POST);
}

Теперь попробуем передать туда какие-то данные:


$url = "http://intop24.ru/demo/curl/post.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;

Результат можно посмотреть здесь: curl_post.php

Отправка файла с помощью CURL

Смысл здесь абсолютно такой же, как и в запросе POST.

Файл, который примет данные: http://intop24.ru/demo/curl/upload_file.php.


print_r($_FILES);
print_r($_POST);

Теперь попробуем передать туда какие-то данные:


$upload = 'test_file.jpg';
$postdata = array( 'name' => 'German',
                   'email' => 'krutovgerman2007@ya.ru',
                   'message' => 'Какое-то сообщение от пользователя German',
                   'upload' => "@".$upload );

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://intop24.ru/demo/curl/upload_file.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$output = curl_exec($ch);
if ($output === FALSE) {
    //Тут-то мы о ней и скажем
    echo "cURL Error: " . curl_error($ch);
    return;
}
print_r($output);
curl_close($ch);

Результат можно посмотреть здесь: curl_post_file.php

Загрузка файла - это тот же самый POST-запрос, однако перед путем к файлу стоит знак "@", что и обозначает, что нужно это передать не как $_POST, а как $_FILES.

HTTP аутентификация с помощью CURL

Довольно полезная штука.


$url = "http://www.site.com/";

$ch = curl_init();

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

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

// если перенаправление разрешено
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// то сохраним наши данные в cURL
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 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);