Использование curl. Пересылка Web-файлов из командной строки. Пример CURL – вызываем удаленный скрипт и получаем результат

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 запросах.

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

  • Инициализация
  • Назначение параметров
  • Выполнение и выборка результата
  • Освобождение памяти

// 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: $url\n"; 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\n"; } else { echo "$test_name: no redirection\n"; } } echo "\n\n"; }

Сначала мы указываем список 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:

Print_r($_POST);

Затем мы создаем 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.

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

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

Print_r($_FILES);

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

$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 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) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; 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:[email protected]: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 в своих корыстных целях. Я надеюсь, что вам понравилась данная статья.

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

cURL — это инструмент, позволяющий взаимодействовать с различными серверами и поддерживающий множество протоколов: HTTP, FTP, TELNET и др. Изначально cURL — это служебная программа для командной строки. Но, к счастью для нас, PHP поддерживает работу с библиотекой cURL. В этой статье мы рассмотрим нетривиальные примеры работы с cURL.

Почему cURL?

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

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

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

cUrl — мощный инструмент, который поддерживает множество протоколов и предоставляет полную информацию о запросе.

Основы cUrl

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

  1. Инициализация.
  2. Установка опций.
  3. Выполнение запроса.
  4. Очистка ресурсов.
// 1. инициализация $ch = curl_init(); // 2. устанавливаем опции, включая урл curl_setopt($ch, CURLOPT_URL, "http://www.google.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. выполнение запроса и получение ответа $output = curl_exec($ch); // 4. очистка ресурсов curl_close($ch);

В основном в этой статье мы будем рассматривать шаг №2, так как там происходит основная магия. Список cURL опций очень большой, поэтому все опции рассматривать сегодня мы не будем, а используем те, которые пригодятся для решения конкретных задач.

Отслеживание ошибок

При необходимости, вы можете добавить следующие строки для отслеживания ошибок:

// ... $output = curl_exec($ch); if ($output === FALSE) { echo "cURL Error: " . curl_error($ch); } // ...

Обратите внимание, мы используем «===» вместо «==», т.к. надо отличать пустой ответ сервера от булевского значения 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»

Отслеживание редиректов, в зависимости от браузера

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

Мы будем использовать опцию CURLOPT_HTTPHEADER для установки наших собственных заголовков, включая User-Agent и язык и посмотрим, куда перенаправляют нас сайты.

// URLs $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: $url\n"; foreach ($browsers as $test_name => $browser) { $ch = curl_init(); // установим адрес 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); // нужны только заголовки 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\n"; } else { echo "$test_name: no redirection\n"; } } echo "\n\n"; }

В цикле проверяем браузеры для каждого урла. Сперва мы устанавливаем опции для нашего запроса: URL и тестируемый браузер и язык.

Т.к. мы установили специальную опцию, результат выполнения запроса будет содержать только HTTP заголовки. С помощью простого регулярного выражения мы можем проверить содержит ли ответ строку «Location:».

Результат выполнения скрипта:

URL: http://www.cnn.com standard: redirects to http://edition.cnn.com/ iphone: redirects to http://edition.cnn.com/ french: redirects to http://edition.cnn.com/ URL: http://www.mozilla.com standard: redirects to https://www.mozilla.org/firefox/ iphone: redirects to https://www.mozilla.org/firefox/ french: redirects to https://www.mozilla.org/firefox/ URL: http://www.facebook.com standard: redirects to https://www.facebook.com/ iphone: redirects to http://m.facebook.com/?refsrc=http%3A%2F%2Fwww.facebook.com%2F&_rdr french: no redirection

Отправляем POST запросы

При выполнении GET запросов данные можно передавать в строке запроса. Например, когда вы ищете в гугле, ваш запрос передается в URL:

Http://www.google.com/search?q=google

Чтобы получить результат этого запроса, вам даже не понадобится cURL, вы можете быть ленивым и использовать «file_get_contents()».

Но некоторые HTML формы используют метод POST. В таком случае данные отправляются в теле сообщения запроса, а не в самом URL.

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

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "FooBar", "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;

Данный скрипт выведет:

Array ( => bar => FooBar => Submit)

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

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

Так же как и в предыдущем примере, создадим файл, который будет принимать запросы, upload_output.php :

Print_r($_FILES);

И сам скрипт, загружающий файлы:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // файл для загрузки "upload" => "@/tmp/desert.jpg"); $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 запроса, поставив вначале «@». Результат работы скрипта:

Array ( => Array ( => desert.jpg => application/octet-stream => /tmp/phpAhEvXy => 0 => 845941))

Multi cURL

Одна из продвинутых возможностей cURL в PHP — это возможность выполнения нескольких запросов одновременно и асинхронно.

В обычных условиях скрипт останавливается и ждет выполнения запроса. И если вам надо выполнить много запросов, то это может занять много времени, т.к. вы будете выполнять последовательно. Это ограничение можно обойти:

// создаем обработчики $ch1 = curl_init(); $ch2 = curl_init(); // устанавливаем опции 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); //create the multiple cURL handle $mh = curl_multi_init(); // добавляем обработчики curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $running = null; // выполняем запросы do { curl_multi_exec($mh, $running); } while ($running > 0); // освободим ресурсы curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Идея состоит в том, что вы можете создать множество cURL дескрипторов, объединить их под одним мульти-дескриптором и выполнять их асинхронно.

Сначала все как и с обычным cURL запросом — создается дескриптор (curl_init() ), задаются параметры (curl_setopt() ). Далее создается мульти-дескриптор (curl_multi_init() ) и добавляются ранее созданные обычные дескрипторы (curl_multi_add_handle() ). Вместо обычного вызова curl_exec() мы будем многократно вызывать curl_multi_exec() данная функция информирует нас о количестве активных соединений с помощью второго параметра — $running. Поэтому цикл работает пока $running не станет равным 0. И, конечно, после окончания работы необходимо освободить ресурсы.

В данном примере мы просто выводим результат запросов в STDOUT. Рассмотрим нетривиальный случай применения multi cURL.

Проверка внешних ссылок в WordPress

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

Напишем скрипт, который найдет все нерабочие ссылки и покажет их нам.

Для начала нам необходимо вытащить все внешние ссылки из базы данных:

// CONFIG $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "сайт"); $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 as $url) { // фильтруем ненужные домены $tmp = parse_url($url); if (isset($tmp["host"]) && 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"); }

В этой части скрипта мы просто вытаскиваем из базы все внешние ссылки. Проверим их:

$mh = curl_multi_init(); // 1. добавим ссылки for ($i = 0; $i < $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // основной цикл do { curl_multi_exec($mh, $curRunning); // 2. один из потоков завершил работу if ($curRunning != $running) { $mhinfo = curl_multi_info_read($mh); if (is_array($mhinfo) && ($ch = $mhinfo["handle"])) { // 3. один из запросов выполнен, можно получить информацию о нем $info = curl_getinfo($ch); // 4. нерабочая ссылка if (!$info["http_code"]) { $dead_urls = $info["url"]; // 5. 404? } else if ($info["http_code"] == 404) { $not_found_urls = $info["url"]; // 6. верная ссылка } else { $working_urls = $info["url"]; } // 7. удаляем отработавший дескриптор curl_multi_remove_handle($mh, $mhinfo["handle"]); curl_close($mhinfo["handle"]); // 8. добавим новый урл add_url_to_multi_handle($mh, $url_list); $running = $curRunning; } } } while ($curRunning > 0); curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n", $dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n", $not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n", $working_urls); echo "\n\n"; // 9. добавляет дескриптор с заданным урлом function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если еще есть ссылки if (isset($url_list[$index])) { // все как обычно $ch = curl_init(); // устанавливаем опции 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); $index++; } }

Рассмотрим код подробнее (нумерация соответствует комментариям в коде):

  1. Добавляем начальное количество дескрипторов, чтобы не перегружать систему потоками. Количество регулируется переменной $max_connections.
  2. В переменной $curRunning хранится количество работающих потоков, в $running — предыдущее значение, если они станут не равными, то один из потоков завершил работу.
  3. Получаем информацию о выполненном запросе.
  4. Если нет ответа сервера — ссылка не рабочая.
  5. Ответ сервера — 404.
  6. Иначе ссылка работает.
  7. Запрос выполнен, освобождаем ресурсы.
  8. Добавим новый урл к мульти дескриптору.
  9. Функция add_url_to_multi_handle() добавляет новый дескриптор с заданным урлом к мульти-дескриптору.

Запустим скрипт:

Dead URLs== xample1234.com/ ==404 URLs== www.google.com/dsfasdfafd ==Working URLs== ru.php.net/manual/ru/function.time.php www.cssbuttongenerator.com/ csslint.net/ codex.wordpress.org/Plugin_API/Action_Reference fortawesome.github.io/Font-Awesome/ fortawesome.github.io/Font-Awesome/ www.oracle.com/technetwork/java/javafx/downloads/index.html codex.wordpress.org/Plugin_API/Filter_Reference codex.wordpress.org/Roles_and_Capabilities code.google.com/p/google-api-php-client/wiki/OAuth2#Google_APIs_Console jplayer.org/ code.google.com/p/google-api-php-client/ developers.google.com/+/ accounts.google.com/ServiceLogin?service=devconsole&passive=1209600&continue=https%3A%2F%2Fcode.google.com%2Fapis%2Fconsole%2F&followup=https%3A%2F%2Fcode.google.com%2Fapis%2Fconsole%2F daneden.github.io/animate.css/ github.com/daneden/animate.css ru2.php.net/manual/ru/function.autoload.php www.google.com/recaptcha/api/verify phpunit.de/ phpunit.de/manual/current/en/phpunit-book.html

Проверка заняла около 2 секунд. Запуская одновременно по 10 потоков производительность возрастает в 10 раз, по сравнению с обычными cURL запросами. Чтобы получить содержимое ответа сервера используйте функцию curl_multi_getcontent($ch) , где $ch — дескриптор, полученный из curl_multi_info_read() .

Другие возможности cURL в PHP

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

Если 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 = "ftp://username:[email protected]: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")); curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = curl_exec($ch); curl_close($ch);

Использование прокси

Запросы можно выполнять через определенный proxy:

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

Колбэки (callback functions)

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

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://example.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 в PHP. В следующий раз, когда вам понадобится делать URL запросы — используйте cURL.

Библиотека CURL (Client URLs) позволяет передавать файлы на удаленный компьютер, используя множество Интернет протоколов. Она имеет очень гибкую настройку и позволяют выполнить практически любой удаленный запрос.

CURL поддерживает протоколы HTTP, HTTPS, FTP, FTPS, DICT, TELNET, LDAP, FILE, и GOPHER, так же как HTTP-post, HTTP-put, cookies, FTP-закачкe, продолжение прерванной передачи файлов, пароли, номера портов, сертификаты SSL, Kerberos и прокси.

Используя CURL, web-сервер может выступать полноценным клиентом любого основанного на HTTP протоколе сервисе, к примеру: XML-RPC, SOAP, или WebDAV.

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

  1. Создание ресурса CURL c помощью функции curl_init.
  2. Установка параметров c помощью функции curl_setopt.
  3. Выполнение запроса c помощью функции curl_exec.
  4. Освобождение ресурса CURL c помощью функции curl_close.

Простой пример использования CURL

// Иницализация библиотеки curl
if ($ch = @ curl_init ())
{
// Устанавливаем URL запроса
@ curl_setopt ($ch , CURLOPT_URL , "http://server.com/" );
// При значении true CURL включает в вывод заголовки
@
// Куда помещать результат выполнения запроса:
// false - в стандартный поток вывода,
// true - в виде возвращаемого значения функции curl_exec.
@
// Максимальное время ожидания в секундах
@
// Установим значение поля User-agent
@ curl_setopt ($ch , CURLOPT_USERAGENT , "PHP Bot (http://blog.yousoft.ru)" );
// Выполнение запроса
$data = @ curl_exec ($ch );
// Вывести полученные данные
echo $data ;
// Особождение ресурса
@ curl_close ($ch );
}
?>

Пример использования GET запроса

$ch = curl_init ();
// GET запрос указывается в строке URL
curl_setopt ($ch , CURLOPT_URL , "http://server.com/?s=CURL" );
curl_setopt ($ch , CURLOPT_HEADER , false );
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , true );
curl_setopt ($ch , CURLOPT_CONNECTTIMEOUT , 30 );

$data = curl_exec ($ch );
curl_close ($ch );
?>

Посылка GET запроса ничем не отличается от получения страницы. Важно заметить, что строка запроса формируется следующим образом:

Http://server.com/index.php?name1=value1&name2=value2&name3=value3

где http://server.com/index.php - адрес страницы, nameX - название переменной, valueX - значение переменной.

Пример использования POST запроса

$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , "http://server.com/index.php" );
curl_setopt ($ch , CURLOPT_HEADER , false );
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , true );
// Нужно явно указать, что будет POST запрос
curl_setopt ($ch , CURLOPT_POST , true );
// Здесь передаются значения переменных
curl_setopt ($ch , CURLOPT_POSTFIELDS , "s=CURL" );
curl_setopt ($ch , CURLOPT_CONNECTTIMEOUT , 30 );
curl_setopt ($ch , CURLOPT_USERAGENT , "PHP Bot (http://mysite.ru)" );
$data = curl_exec ($ch );
curl_close ($ch );
?>

Отправка POST запроса не многим отличается от отправки GET запроса. Все основные шаги остаются такие же. Переменные также задаются парами: name1=value1&name2=value2 .

Пример HTTP-авторизации

// HTTP авторизация
$url = "http://server.com/protected/" ;
$ch = curl_init ();


curl_setopt ($ch , CURLOPT_USERPWD , "myusername:mypassword" );
$result = curl_exec ($ch );
curl_close ($ch );
echo $result ;
?>

Пример FTP-сессии

$fp = fopen (__FILE__ , "r" );
$url = "ftp://username:[email protected]:21/path/to/newfile.php" ;
$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_FTPASCII , 1 );
curl_setopt ($ch , CURLOPT_INFILESIZE , filesize (__FILE__ ));
$result = curl_exec ($ch );
curl_close ($ch );
?>

При возникновении проблем в использовании cURL необходимо добавить следующие строки перед вызовом curl_close для получения отчета о последнем выполненном запросе:

print_r (curl_getinfo ($ch ));
echo "cURL error number:" . curl_errno ($ch ). "
" ;
echo "cURL error:" . curl_error ($ch ). "
" ;
curl_close ($ch );
?>

c URL очень полезный инструмент командной строки для передачи данных от или к серверу. Curl поддерживает различные протоколы, такие как FILE, HTTP, HTTPS, IMAP, IMAPS, LDAP, DICT, LDAPS, TELNET, FTPS, GOPHER, RTMP, RTSP, SCP, SFTP, POP3, POP3S, SMB, SMBS, SMTP, SMTPS, и TFTP.

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

1. Проверьте URL

Одним из наиболее распространенных и простейших применений cURL печатает саму команду, а затем URL, который вы хотите проверить

Curl https://domain.ru

Эта команда будет отображать содержимое URL на вашем терминале

2. Сохраните вывод URL в файл

Curl -o website https://domain.ru % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 41793 0 41793 0 0 275k 0 --:--:-- --:--:-- --:--:-- 2.9M

В этом примере, вывод будет сохранен в файл с именем ‘website’ в текущем рабочем каталоге.

3. Загрузка файлов с помощью Curl

Вы можете скачивать файлы при помощи Curl, путем добавления опции -o к команде. Он используется для сохранения файлов на локальном сервере с теми же именами, как и на удаленном сервере

Curl -O https://domain.ru/file.zip

В этом примере архив ‘file.zip’ будет загружен в текущий рабочий каталог.

Вы также можете загрузить файл с другим именем, добавив опцию -o к cURL.

Curl -o archive.zip https://domain.ru/file.zip

Таким образом, архив ‘file.zip’ будет загружен и сохранен как ‘Archive.zip’.

cURL может быть также использован для загрузки нескольких файлов одновременно, как показано в приведенном ниже примере

Curl -O https://domain.ru/file.zip -O https://domain.com/file2.zip

Curl также можно использовать для загрузки файлов надежно через SSH с помощью следующей команды

Curl -u user sftp://server.domain.ru/path/to/file

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

4. Взять информацию из заголовка HTTP веб-сайта

Вы можете легко получить информацию заголовка HTTP из любого веб-сайта, добавив опцию -I (‘i’) к cURL.

Curl -I http://domain.ru HTTP/1.1 200 OK Date: Sun, 16 Oct 2016 23:37:15 GMT Server: Apache/2.4.23 (Unix) X-Powered-By: PHP/5.6.24 Connection: close Content-Type: text/html; charset=UTF-8

5. Доступ к FTP-серверу

Чтобы получить доступ к FTP-серверу с помощью Curl, надо использовать следующую команду

Curl ftp://ftp.domain.ru --user username:password

Curl будет подключаться к FTP-серверу и выведет список всех файлов и каталогов в домашнем каталоге пользователя

Вы можете скачать файл с помощью FTP

Curl ftp://ftp.domain.ru/file.zip --user username:password

и загрузить файл на сервер FTP

Curl -T file.zip ftp://ftp.domain.ru/ --user username:password

Вы можете проверить страницу Curl вручную, чтобы увидеть все доступные опции cURL и его функциональные возможности

Man curl

PS. Если вам понравился этот пост, пожалуйста поделитесь им с друзьями в социальных сетях с помощью кнопок ниже или просто оставьте комментарий. Благодарю.

Это руководство предназначено для тех web-разработчиков, которые хотят автоматизировать передачу файлов по сети либо взаимодействовать с другими Интернет - сервисами. Для чтения этой главы вам необходимо владеть пониманием принципа работы стратегии клиент - сервер и знать основы синтаксиса PHP.

cURL и libcurl - библиотеки, позволяющие серверу передавать файлы на удаленный компьютер, используя множество Интернет протоколов. Библиотеки имеют очень гибкую настройку и позволяют выполнить практически любой удаленный запрос. Используя их, web-сервер может выступать полноценным клиентом любого основанного на HTTP протоколе сервисе, к примеру: XML-RPC, SOAP, или WebDAV.

В этой статье будет рассказано о том, что такое cURL, как его использовать из командной строки, и о его применении в PHP.

Что такое cURL и libcurl

cURL является сокращением от "Client URLs". Он был разработан Daniel Stenberg в 1998 году как утилита, работающая из командной строки. Libcurl - переносимая библиотека, предоставляющая простой API-интерфейс к функциональности cURL. Библиотека безопасна в мультипоточной среде, совместима с IPv6 и поддерживает постоянные соединения. Интерфейс взаимодействия с php был добавлен Sterling Hughes.

cURL и libcurl могут использоваться для передачи информации с использованием таких протоколов, как HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET и FILE. Реализована поддержка практически всех *nix систем, а также Windows, OS/2, BeOS и некоторых других.

Библиотека curl - Open Source продукт с оригинальной MIT/X лицензией, позволяющей использовать этот пакет в любых: как коммерческих, так и некоммерческих целях, включать ее в свой дистрибутив (даже если он распространяется без открытого исходного кода).

Необходимо понимать, что cURL не имеет ничего общего с Curl Corporation, являющейся коммерческим производителем языка программирования Curl.

Инсталляция cURL

Для работы в PHP версии 4.2.3 и выше вам необходим cURL версии не ниже 7.9.0. Для работы в PHP версии 4.3.0 и выше вам необходим cURL версии не ниже 7.9.8.

Windows

Как и любой другой дополнительный модуль, он требует проинсталлированного дистрибутива PHP. Для установки cURL скопируйте файлы php4ts.dll, ssleay32.dll, php_curl.dll, msvcrt.dll из каталога DLL в системную директорию Windows, как правило, это:

C:\windows\system для Windows 9x/Me c:\winnt\system32 для Windows NT/2000 c:\windows\system32 для Windows XP.

После этого необходимо раскомментировать строку

;extension=php_curl.dll

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

dl ("php_curl.dll" );
?>

Unix

Ближайшее зеркало, содержащее исходные коды и откомпилированные бинарные файлы для различных операционных систем, вы можете найти на сайте http://curl.haxx.se/ .

Поскольку cURL использует библиотеку openssl для SSL соединений, вначале необходимо установить на север SSL. В случае, если при инсталляции cURL библиотека openssl найдена не будет, произойдет установка cURL без поддержки SSL соединений.

Инсталляция cURL состоит из следующих шагов: ./configure, make, make install.

После этого необходимо пересобрать PHP c опцией --with-curl

О том, включена ли поддержка cURL в php, вы можете узнать, выполнив phpinfo().

Пример использования cURL

Использование cURL из командной строки очень просто. Следующий пример запрашивает web-страницу и выводит ее в stdout

$ curl -L zend.com

M(опция -L разрешает переадресации)

Также возможно использование cURL из командной строки при помощи PHP. Следующий пример запрашивает 3 страницы и выводит их на экран

$var = echo shell_exec ("/usr/bin/curl -L http://www.zend.com http://zend.com/developers.php http://zend.com/zend/tut/" );
?>

Пример использования cURL в PHP

Использование libcurl в php-скрипте является достаточно простым, особенно для таких операций, как генерация POST-запросов.

Для использования libcurl необходимо выполнить следующие шаги:

  • Инициализировать сессию cURL
  • Установить опции cURL (порядок установки опций не имеет значения)
  • Выполнить запрос
  • Завершить сессию cURL

Для демонстрации вышеперечисленного приведем практические примеры использования cURL для генерации POST-запроса, HTTP-авторизации, FTP-сессии.

// Поиск книг на сервере amazon.com
$url = "http://www.amazon.com/exec/obidos/search-handle-form/002-5640957-2809605" ;
$ch = curl_init ();
// set url to post to
curl_setopt ($ch , CURLOPT_FAILONERROR , 1 );
curl_setopt ($ch , CURLOPT_FOLLOWLOCATION , 1 ); // allow redirects
// return into a variable
curl_setopt ($ch , CURLOPT_TIMEOUT , 3 ); // times out after 4s
curl_setopt ($ch , CURLOPT_POST , 1 ); // set POST method
curl_setopt ($ch , CURLOPT_POSTFIELDS , "url=index%3Dbooks&field-keywords=PHP+MYSQL" ); // add POST fields
$result = curl_exec ($ch ); // run the whole process
curl_close ($ch );
echo $result ;
?>

// HTTP authentication
$url = "http://www.example.com/protected/" ;
$ch = curl_init ();
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt ($ch , CURLOPT_URL , $url );
curl_setopt ($ch , CURLOPT_USERPWD , "myusername:mypassword" );
$result = curl_exec ($ch );
curl_close ($ch );
echo $result ;
?>

// FTP this script to a server
$fp = fopen (__FILE__ , "r" );
$url = "ftp://username:[email protected]:21/path/to/newfile.php" ;
$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_FTPASCII , 1 );
curl_setopt ($ch , CURLOPT_INFILESIZE , filesize (__FILE__ ));
$result = curl_exec ($ch );
curl_close ($ch );
?>

При возникновении проблем в использовании cURL необходимо добавить следующие строки перед вызовом curl_close для получения отчета о последнем выполненном запросе:

print_r (curl_getinfo ($ch ));
echo "\n\ncURL error number:" . curl_errno ($ch );
echo "\n\ncURL error:" . curl_error ($ch );
// ...close cURL handle ($ch) below
?>

Решение о том, что использовать: cURL или libcurl, - стоит принимать в зависимости от обстоятельств. В случае, если Вы пишете выполняемый из командной строки скрипт, либо у Вашего провайдера нет поддержки libcurl, имеет смысл использовать cURL. В остальных случаях использование libcurl оказывается более удобным.




Есть еще вопросы или что-то непонятно - добро пожаловать на наш