Пример использования в php библиотеки curl для создания запросов get/post
Содержание:
- Загружаем и сохраняем изображения со страницы с помощью cURL
- Авторизация с помощью cURL
- POST запрос¶
- Twitter: проверяем отношения между двумя пользователями
- Получение информации о запросе cUrl
- Отправка файлов
- Curl и FTP
- 5 последних уроков рубрики «PHP»
- 👨💻 Опрос
- Загрузка файла
- PHP cURL multiple async requests
- Получение и отправка заголовков
- 8. User Agent
- Запросы и ответы содержат заголовки
- Получаем последний статус Twitter
- Получаем информацию о размере файла с помощью cURL
- Пример работы с библиотекой
- Протокол HTTP
- Параллельные cURL запросы в PHP
- Загрузка через FTP с помощью cURL
- POST запросы cUrl в PHP
Загружаем и сохраняем изображения со страницы с помощью cURL
Данная функция может быть очень полезна: задаем ей URL страницы и она сохраняет все изображения с нее на вашем сервере.
function getImages($html) { $matches = array(); $regex = '~http://somedomain.com/images/(.*?)\.jpg~i'; preg_match_all($regex, $html, $matches); foreach ($matches as $img) { saveImg($img); } } function saveImg($name) { $url = 'http://somedomain.com/images/'.$name.'.jpg'; $data = get_data($url); file_put_contents('photos/'.$name.'.jpg', $data); } $i = 1; $l = 101; while ($i < $l) { $html = get_data('http://somedomain.com/id/'.$i.'/'); getImages($html); $i += 1; }
Авторизация с помощью cURL
HTTP Авторизация
Чтобы с помощью cURL авторизироваться на сайте, который использует Basic HTTP-аутентификацию нужно установить опцию CURLOPT_USERPWD, в которой будет наш логин и пароль.
Пример:
$login = 'test_login'; // наш логин $password = 'test_password'; // наш пароль $url = 'https://phpstack.ru/'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_USERPWD, "$login:$password"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, false); $result = curl_exec($ch); curl_close($ch);
OAuth авторизация
$url = 'https://phpstack.ru/'; $oauthToken = 'Bearer dsfgdsfgdsfgdsfgdsfg'; // наш токен $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: $oauthToken")); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, false); $html = curl_exec($ch); curl_close($ch);
Авторизация через форму
Давайте применим полученные нами знания и авторизируемся на каком-нибудь сайте. Для этого нужно посмотреть куда форма отправляет данные и отправить туда то же самое.
Допустим на сайте есть такая форма:
<html> <body> <form method = "POST" action="https://phpstack.ru/admin/' > <input name="login" type="text"> <input name="password" type="text"> <input type="submit" name="submit" value="Отправить" > </form> </body> </html>
Тогда наш cURL запрос должен быть сформирован так:
$url = 'http://phpstack.ru/admin/'; // url, на который отправляется запрос $postData = [ // поля нашего запроса 'login' => 'our_login', // наш логин 'password' => 'our_password', // наш пароль ]; $cookieFile = __DIR__ . '/cookie.txt'; // притворяемся браузером $headers = [ 'Connection: keep-alive', 'Upgrade-Insecure-Requests: 1', 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding: gzip, deflate', 'Accept-Language: ru,en-US;q=0.9,en;q=0.8', ]; $post_data = http_build_query($post_data); $curl = curl_init(); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_VERBOSE, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile); curl_setopt($curl, CURLOPT_COOKIEJAR, $cookieFile); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); // true $result = curl_exec($curl);
В $result у нас ответ сервера, мы можем проверить, что на странице находится сообщение об успешной авторизации и дальше гулять по личному кабинету сайта. Да, кстати, не используйте эти знания в противоправных целях.
POST запрос¶
Примечание
httpbin — сервис для отладки HTTP запросов и
ответов
Пример POST запроса к сервису httpbin.
POST запрос на сайт https://httpbin.org/post
#include <stdio.h> #include <curl/curl.h> int main(void) { CURL *curl; CURLcode res; /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { /* First set the URL that is about to receive our POST. This URL can just as well be a https:// URL if that is what should receive the data. */ curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); /* Now specify the POST data */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=UrFU&project=lectures.www"); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); return ; }
Ответ в формате JSON
{ "args" {}, "data" "", "files" {}, "form" { "name" "UrFU", "project" "lectures.www" }, "headers" { "Accept" "*/*", "Content-Length" "30", "Content-Type" "application/x-www-form-urlencoded", "Host" "httpbin.org" }, "json" null, "url" "https://httpbin.org/post" }
Twitter: проверяем отношения между двумя пользователями
Если вам нужно узнать, читает ли ваши твиты определенный пользователь, то можно задействовать API Twitter. Данный скрипт выводит , если два пользователя, указанные на строчках 17 и 18, находятся в дружеских отношениях на Twitter. В противном случае возвращается .
function make_request($url) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); $result = curl_exec($ch); curl_close($ch); return $result; } /* Получаем соответствие */ function get_match($regex,$content) { preg_match($regex,$content,$matches); return $matches; } /* Персоны для проверки */ $person1 = 'phpsnippets'; $person2 = 'catswhocode'; /* Отправляем запрос на twitter */ $url = 'https://api.twitter.com/1/friendships/exist'; $format = 'xml'; /* Проверка */ $persons12 = make_request($url.'.'.$format.'?user_a='.$person1.'&user_b='.$person2); $result = get_match('/<friends>(.*)<\/friends>/isU',$persons12); echo $result; // Возвращаем "true" или "false"
Получение информации о запросе cUrl
Чтобы получить исчерпывающую информацию о самом запросе используется функция curl_getinfo(). Главным образом эта информация полезна для отладки работы скрипта, в котором выполняются cURL запросы.
curl_exec($ch); $info = curl_getinfo($ch); echo 'Запрос для url ' . $info . ' занял ' . $info . ' секунд ';
Функция возвращает данные в виде массива со следующими ключами:
- 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
Отправка файлов
Для того, чтобы отправить файлы на сервер, мы просто заполняем поля POST запроса, указывая там специальный класс CURLFile. На сервере вы можете получить отправленные файлы, при помощи суперглобального массива $_FILES.
$url = 'https://phpstack.ru/'; $postFields = [ 'photo1' => new \CURLFile( __DIR__ . '/img1.jpg' ), 'photo2' => new \CURLFile( __DIR__ . '/img2.jpg' ), ]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, false); $html = curl_exec($ch); curl_close($ch);
Curl и FTP
Утилита поддерживает FTP! Вы можете использовать её для загрузки файлов с удалённого сервера.
curl -u username:password -O ftp://sampleftpserver/testfile.tar.gz
В приведённой выше команде ftp://sampleftpserver — это FTP-сервер, который принимает соединения. Вы можете не указывать имя пользователя и пароль для анонимных FTP-соединений. Введите команду и посмотрите, как заполняется индикатор выполнения.
Вы также можете загружать файлы с помощью этой команды:
curl -u username:password -T testfile.tar.gz ftp://sampleftpserver
Опять же таки, мы можем пропустить имя пользователя и пароль для анонимных FTP-соединений.
5 последних уроков рубрики «PHP»
Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак
В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение
В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.
👨💻 Опрос
Проверьте свою внимательность. Что означают следующие параметры?
Tip: Использование curl в Терминале или iTerm OS Mac обеспечивают намного более простую работу, чем использование командной строки в Windows. Если серьезно относиться к документации API, работая на ПК, стоит подумать о переходе с OS Windows. Будет много утилит, которые мы установим при помощи Терминала, который просто работает на Mac. Кроме того, находясь в Силиконовой долине, и используя ПК вместо Mac можно показаться старомодным для окружающих (см. Почему большинство стартапов покупают MacBook для своих сотрудников).
Для более подробного изучения curl в документировании REST API можно посмотреть REST-esting with curl.
Загрузка файла
Загрузка файла будет выглядеть практически так же, как и обычный POST запрос, так как все формы загрузки файла работают только с ним.
Сначала давайте создадим файл для того, чтобы сформировать его и отправить файлу 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 переменную, предварительно поместив перед ней символ @. При запуске написанного скрипта вы получите следующий результат:
PHP cURL multiple async requests
The function creates a new multi handle, which
allows the processing of multiple cURL handles asynchronously.
multi_async.php
<?php $urls = [ "http://webcode.me", "https://example.com", "http://httpbin.org", "https://www.perl.org" ]; $options = ; $mh = curl_multi_init(); $chs = []; foreach ($urls as $url) { $ch = curl_init($url); curl_setopt_array($ch, $options); curl_multi_add_handle($mh, $ch); $chs[] = $ch; } $running = false; do { curl_multi_exec($mh, $running); } while ($running); foreach ($chs as $h) { curl_multi_remove_handle($mh, $h); } curl_multi_close($mh); foreach ($chs as $h) { $status = curl_getinfo($h, CURLINFO_RESPONSE_CODE); echo $status . "\n"; } foreach ($chs as $h) { echo "----------------------\n"; echo curl_multi_getcontent($h); }
In the example, we create asynchronous requests to four websites. We print their
status codes and headers.
$mh = curl_multi_init();
We initiate the multi handle.
foreach ($urls as $url) { $ch = curl_init($url); curl_setopt_array($ch, $options); curl_multi_add_handle($mh, $ch); $chs[] = $ch; }
We create standard handles for each URLs and add them to the multi handle with
.
$running = false; do { curl_multi_exec($mh, $running); } while ($running);
We execute all queries asynchronously, and continue when all are complete.
foreach ($chs as $h) { curl_multi_remove_handle($mh, $h); } curl_multi_close($mh);
We close the handles.
foreach ($chs as $h) { $status = curl_getinfo($h, CURLINFO_RESPONSE_CODE); echo $status . "\n"; }
We get the status codes.
foreach ($chs as $h) { echo "----------------------\n"; echo curl_multi_getcontent($h); }
We get the headers.
$ php multi_req.php 200 200 200 200 ---------------------- HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Mon, 08 Feb 2021 16:37:31 GMT Content-Type: text/html Content-Length: 348 Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT Connection: keep-alive ETag: "5d32ffc5-15c" Accept-Ranges: bytes ---------------------- HTTP/2 200 content-encoding: gzip accept-ranges: bytes age: 285367 cache-control: max-age=604800 content-type: text/html; charset=utf-8 date: Mon, 08 Feb 2021 16:36:11 GMT etag: "3147526947" expires: Mon, 15 Feb 2021 16:36:11 GMT last-modified: Thu, 17 Oct 2019 07:18:26 GMT server: ECS (dcb/7F83) x-cache: HIT content-length: 648 ---------------------- HTTP/1.1 200 OK Date: Mon, 08 Feb 2021 16:36:11 GMT Content-Type: text/html; charset=utf-8 Content-Length: 9593 Connection: keep-alive Server: gunicorn/19.9.0 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true ---------------------- HTTP/2 200 server: Combust/Plack (Perl) content-type: text/html; charset=utf-8 last-modified: Mon, 08 Feb 2021 15:29:36 GMT x-content-type-options: nosniff x-frame-options: deny x-xss-protection: 1 strict-transport-security: max-age=15768000 via: 1.1 varnish, 1.1 varnish accept-ranges: bytes date: Mon, 08 Feb 2021 16:36:11 GMT age: 2713 x-served-by: cache-lga21948-LGA, cache-vie21642-VIE x-cache: HIT, HIT x-cache-hits: 2, 1 x-timer: S1612802172.507868,VS0,VE1 content-length: 12011
Получение и отправка заголовков
По умолчанию, заголовки ответа сервера не показываются. Но это можно исправить:
> curl -i google.com HTTP/1.1 301 Moved Permanently Location: http://www.google.com/ Content-Type: text/html; charset=utf-8 Date: Sun, 16 Sep 2018 08:28:18 GMT Expires: Tue, 16 Oct 2018 08:28:18 GMT Cache-Control: public, max-age=2592000 Server: gws Content-Length: 219 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>301 Moved</TITLE></HEAD><BODY> <H1>301 Moved</H1> The document has moved <A HREF="http://www.google.com/">here</A>. </BODY></HTML>
Если содержимое страницы не нужно, а интересны только заголовки (будет отправлен запрос):
> curl -I http://www.example.com/ HTTP/1.1 200 OK Date: Sun, 16 Sep 2018 08:20:52 GMT Server: Apache/2.4.34 (Win64) mod_fcgid/2.3.9 X-Powered-By: PHP/7.1.10 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Set-Cookie: PHPSESSID=svn7eb593i8d2gv471rs94og58; path=/ Set-Cookie: visitor=fa867bd917ad0d715830a6a88c816033; expires=Mon, 16-Sep-2019 08:20:53 GMT; Max-Age=31536000; path=/ Set-Cookie: lastvisit=1537086053; path=/ Content-Length: 132217 Content-Type: text/html; charset=utf-8
Посмотреть, какие заголовки отправляет CURL при запросе, можно с помощью опции , которая выводит более подробную информацию:
> curl -v google.com
- Строка, начинающаяся с означает заголовок, отправленный серверу
- Строка, начинающаяся с означает заголовок, полученный от сервера
- Строка, начинающаяся с означает дополнительные данные от CURL
* Rebuilt URL to: http://google.com/ * Trying 173.194.32.206... * TCP_NODELAY set * Connected to google.com (173.194.32.206) port 80 (#0)
> GET / HTTP/1.1 > Host: google.com > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 301 Moved Permanently < Location: http://www.google.com/ < Content-Type: text/html; charset=utf-8 < Date: Mon, 17 Sep 2018 15:11:49 GMT < Expires: Wed, 17 Oct 2018 15:11:49 GMT < Cache-Control: public, max-age=2592000 < Server: gws < Content-Length: 219 < X-XSS-Protection: 1; mode=block < X-Frame-Options: SAMEORIGIN < <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>301 Moved</TITLE></HEAD><BODY> <H1>301 Moved</H1> The document has moved <A HREF="http://www.google.com/">here</A>. </BODY></HTML>
* Connection #0 to host google.com left intact
Если этой информации недостаточно, можно использовать опции или .
А вот так можно отправить свой заголовок:
> curl -H "User-Agent: Mozilla/5.0" http://www.example.com/
8. User Agent
Все HTTP-запросы поддерживают поле ‘User-Agent’, в котором
указывается клиентское приложение пользователя. Многие web-приложения
используют эту информацию, чтобы тем или иным способом отобразить
страницу. Web-программисты создают несколько версий страницы для
пользователей разных браузеров в целях улучшения внешнего вида,
использования различных скриптов javascript, vbscript и т.д.
Иногда вы можете обнаружить, что curl возвращает страницу не
такой, какой вы ее видели в своем браузере. В этом случае как раз
уместно использовать поле ‘User Agent’, чтобы в очередной раз
обмануть сервер.
Замаскировать curl под Internet Explorer на машине с Windows 2000:
# curl -A "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
Почему бы не стать Netscape 4.73 на Linux-машине (PIII):
# curl -A "Mozilla/4.73 (X11; U; Linux 2.2.15 i686)"
Запросы и ответы содержат заголовки
При вводе адреса веб-сайта мы видим только текст ответа. Но на самом деле происходит гораздо больше процессов. Когда мы делаем запрос, мы отправляем заголовок запроса, который содержит информацию о запросе. Ответ также содержит заголовок ответа.
Для того чтобы увидеть заголовок ответа в запрос curl, добавим ключ :
Заголовок будет включен над телом ответа:
Чтобы в ответе получить только заголовок, используем ключ
Заголовок содержит метаданные ответа. Вся эта информация передается в браузер при запросе URL в нашем браузере (например, при просмотре веб-страницы в Интернете), но браузер не отображает эту информацию. Можно просмотреть информацию заголовка с помощью консоли Chrome Developer Tools, перейдя на вкладку .
Теперь давайте уточним метод. Метод GET (чтение) подразумевается по умолчанию, когда не указан другой метод, но мы сделаем это здесь явно с параметром -X:
При посещении веб-сайта мы отправляем запрос, используя метод GET. Существуют и другие методы HTTP, которые можно использовать при взаимодействии с REST API. Вот общие методы, используемые при работе с конечными точками REST:
HTTP метод | Описание |
---|---|
POST | Создание ресурса |
GET | Чтение (получение) ресурса |
PUT | Обновление ресурса |
DELETE | Удаление ресурса |
Note: Метод GET используется по умолчанию в запросах curl. При использовании curl для выполнения запросов HTTP, отличных от GET, необходимо указывать нужный метод HTTP.
Получаем последний статус Twitter
С помощью PHP и cURL очень просто получить статус определённого пользователя. Данную информацию можно выводить в блоге.
function get_status($twitter_id, $hyperlinks = true) { $c = curl_init(); curl_setopt($c, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/$twitter_id.xml?count=1"); curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); $src = curl_exec($c); curl_close($c); preg_match('/<text>(.*)<\/text>/', $src, $m); $status = htmlentities($m); if( $hyperlinks ) $status = ereg_replace("]+://]+/]", '<a href="%5C%22%5C%5C0%5C%22">\\0</a>', $status); return($status); }
Использовать функцию очень просто:
echo get_status('catswhocode');
Получаем информацию о размере файла с помощью cURL
Как определить размер определенного файла, расположенного на другом сервере? Поможет следующая функция. Она получает 3 параметра: URL файла, и (если требуется) имя пользователя и пароль.
function remote_filesize($url, $user = "", $pw = ""){ ob_start(); $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); if(!empty($user) && !empty($pw)) { $headers = array('Authorization: Basic ' . base64_encode("$user:$pw")); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } $ok = curl_exec($ch); curl_close($ch); $head = ob_get_contents(); ob_end_clean(); $regex = '/Content-Length:\s(.+?)\s/'; $count = preg_match($regex, $head, $matches); return isset($matches) ? $matches : "unknown"; }
Пример работы с библиотекой
Я считаю, что после того, как некоторые общие моменты уже ясны и вроде бы все понятно, то самое время переходить к практике и на примере уже оттачивать свое мастерство. Лично у меня всегда сразу руки чешутся все попробовать на практике 🙂
Раз уж cURL так хорош для парсеров, то рассмотрим функцию получения кода страницы по ее адресу. При этом на выходе получим массив с заголовком, содержимым страницы и даже коды ошибок, если что-то пойдет не так.
Входные параметры:url — адрес страницы или сайта.
Значения выходных параметров (массив с тремя элементами):header — если что-то пошло не так, то тут будет код ошибки.header — здесь при этом будет текст ошибки.header — собственно сама страница\файл\картинка и т.д.
Используем функцию, например, так:
$result = get_web_page( "https://ya.ru" ); if (($result != 0 )||($result != 200)) { echo $result; } else { $page = $result; echo $page; }
Все должно пройти без ошибок и вы получите код страницы в переменной $page. Если же попробовать получить несуществующую страницу , то получим ошибку:
Could not resolve host: yaaaaaaaaaaaa.ru; Host not found
Все обрабатывается корректно и красиво 🙂
Дальше с кодом страницы можно делать все что угодно, например, парсить регулярками. Но это все в следующих уроках, а пока что остановимся на этом.
← PHP — str_replace | | Парсер статистики Liveinternet →
Протокол HTTP
HTTP — это протокол, используемый при приеме данных от
web-серверов. Это очень простой протокол, который построен на TCP/IP.
Протокол также позволяет отправлять информацию на сервер от клиента,
используя несколько методов, как будет показано далее.
HTTP — это строки ASCII-текста, отсылаемые от клиента к серверу
для запроса какого-либо действия. При получении запроса сервер
отвечает клиенту несколькими служебными текстовыми строками, а затем
и собственно контентом.
Используя ключ curl -v, вы можете увидеть, какие команды curl
отсылает серверу, а также другой информационный текст. Ключ -v —
пожалуй, единственная возможность отладить или даже понять
особенности взаимодействия curl и веб-сервера.
Параллельные cURL запросы в PHP
Для чего могут потребоваться многопоточные запросы? Например у нас есть много URL адресов:
$urls = [ 'https://httpbin.org/anything?1', 'https://httpbin.org/anything?2', 'https://httpbin.org/anything?3', ];
И если мы будем по очереди отправлять запросы, то второй запрос начнется только после того, как закончился первый и так далее, а это существенно увеличивает время работы скрипта.
Выглядит это так:
$results = []; foreach ($urls as $url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $results = curl_exec($ch); curl_close($ch); } var_dump($results);
Теперь в $results у нас содержится массив, где ключи — это url адреса, а значения — результаты запросов. Однако запросы выполняются долго. Но мы можем это ускорить.
Как выполнить 3 запроса одновременно? В этом нам поможет
Давайте решим конкретную задачу при помощи параллельных curl запросов. Нам нужно отправить одновременно 3 запроса.
$urls = [ 'https://httpbin.org/anything?1', 'https://httpbin.org/anything?2', 'https://httpbin.org/anything?3', ]; // array of curl handles $multiCurl = []; // data to be returned $results = []; // multi handle $mh = curl_multi_init(); foreach ($urls as $url) { $multiCurl = curl_init(); curl_setopt($multiCurl, CURLOPT_URL, $url); curl_setopt($multiCurl, CURLOPT_HEADER, 0); curl_setopt($multiCurl, CURLOPT_RETURNTRANSFER, 1); curl_multi_add_handle($mh, $multiCurl); } $index = null; do { curl_multi_exec($mh, $index); } while ($index > 0); // get content and remove handles foreach ($multiCurl as $k => $ch) { $results = curl_multi_getcontent($ch); curl_multi_remove_handle($mh, $ch); } // close curl_multi_close($mh); var_dump($results); // в $results у нас содержатся ответы на наши 3 запроса
Такие параллельные запросы выполняются значительно быстрее чем поочередные.
Загрузка через FTP с помощью cURL
PHP имеет библиотеку FTP library, но также можно использовать cURL для загрузки файлов на FTP сервер. Вот рабочий пример:
// Открываем файл $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);
POST запросы cUrl в PHP
$array = array( 'login' => 'user', 'password' => '123' ); $ch = curl_init('https://asgeto.ru'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $array); // Или предать массив строкой: // curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array, '', '&')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, false); $html = curl_exec($ch); curl_close($ch); echo $html;
Функция file_get_contents() так же умеет отправлять POST запросы. Для этого нужно использовать заголовки:
$headers = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL, 'content' => 'login=user&password=123', ), )); echo file_get_contents('https://asgeto.ru', false, $headers);