Базовая работа с php curl: get, post, json, headers

POST (HTTP)

It’s easy to post data using curl. This is done using the option. The post data must be urlencoded.

Post a simple «name» and «phone» guestbook.


How to post a form with curl, lesson #1:

Dig out all the tags in the form that you want to fill in.

If there’s a «normal» post, you use to post. takes a full «post string», which is in the format

The ‘variable’ names are the names set with in the tags, and the data is the contents you want to fill in for the inputs. The data must be properly URL encoded. That means you replace space with + and that you replace weird letters with %XX where XX is the hexadecimal representation of the letter’s ASCII code.

Example:

(page located at )

We want to enter user ‘foobar’ with password ‘12345’.

To post to this, you enter a curl command line like:

While uses the application/x-www-form-urlencoded mime-type, generally understood by CGI’s and similar, curl also supports the more capable multipart/form-data type. This latter type supports things like file upload.

accepts parameters like . If you want the contents to be read from a file, use as contents. When specifying a file, you can also specify the file content type by appending to the file name. You can also post the contents of several files in one field. For example, the field name ‘coolfiles’ is used to send three files, with different content types using the following syntax:

If the content-type is not specified, curl will try to guess from the file extension (it only knows a few), or use the previously specified type (from an earlier file if several files are specified in a list) or else it will use the default type ‘application/octet-stream’.

Emulate a fill-in form with . Let’s say you fill in three fields in a form. One field is a file name which to post, one field is your name and one field is a file description. We want to post the file we have written named «cooltext.txt». To let curl do the posting of this data instead of your favourite browser, you have to read the HTML source of the form page and find the names of the input fields. In our example, the input field names are ‘file’, ‘yourname’ and ‘filedescription’.

To send two files in one post you can do it in two ways:

Send multiple files in a single «field» with a single field name:

Send two fields with two field names

To send a field value literally without interpreting a leading or , or an embedded , use instead of . This is recommended when the value is obtained from a user or some other unpredictable source. Under these circumstances, using instead of could allow a user to trick curl into uploading a file.

Создание 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.

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

Загрузка файла будет выглядеть практически так же, как и обычный 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 переменную, предварительно поместив перед ней символ @. При запуске написанного скрипта вы получите следующий результат:

User Agent

An HTTP request has the option to include information about the browser that generated the request. Curl allows it to be specified on the command line. It is especially useful to fool or trick stupid servers or CGI scripts that only accept certain browsers.

Example:

Other common strings:

  • — Netscape Version 3 for Windows 95
  • — Netscape Version 3 for Windows 95
  • — Netscape Version 2 for OS/2
  • — Netscape for AIX
  • — Netscape for Linux

Note that Internet Explorer tries hard to be compatible in every way:

Mozilla/4.0 (compatible; MSIE 4.01; Windows 95) — MSIE for W95

Mozilla is not the only possible User-Agent name:

  • — KDE File Manager desktop client
  • — Lynx command line browser

Speed Limit

Curl allows the user to set the transfer speed conditions that must be met to let the transfer keep going. By using the switch and you can make curl abort transfers if the transfer speed is below the specified lowest limit for a specified time.

To have curl abort the download if the speed is slower than 3000 bytes per second for 1 minute, run:

This can very well be used in combination with the overall time limit, so that the above operation must be completed in whole within 30 minutes:

Forcing curl not to transfer data faster than a given rate is also possible, which might be useful if you’re using a limited bandwidth connection and you don’t want your transfer to use all of it (sometimes referred to as «bandwidth throttle»).

Make curl transfer data no faster than 10 kilobytes per second:

or

Or prevent curl from uploading data faster than 1 megabyte per second:

When using the option, the transfer rate is regulated on a per-second basis, which will cause the total transfer speed to become lower than the given number. Sometimes of course substantially lower, if your transfer stalls during periods.

Общие команды curl, связанные с REST

У curl много возможных команд, но при работе с REST API наиболее распространены следующие:

curl Команда Описание Пример
или Включает заголовки ответа в ответ
или Включает данные для публикации на URL. Данные должны быть в кодировке URL. Данные также могут быть переданы в теле запроса.
или Отправляет заголовок запроса на ресурс. Заголовки являются общими с запросами REST API, потому что авторизация обычно включается в заголовок
Задает метод HTTP для использования с запросом (в данном примере, ). При использовании в запросе, curl автоматически указывает метод POST. С GET-запросами, в том числе HTTP-метод является необязательным, поскольку GET-метод используется по умолчанию
Загружает контент из файла

В документации curl есть полный список команд curl.

Запросы и ответы содержат заголовки

При вводе адреса веб-сайта мы видим только текст ответа. Но на самом деле происходит гораздо больше процессов. Когда мы делаем запрос, мы отправляем заголовок запроса, который содержит информацию о запросе. Ответ также содержит заголовок ответа.

Для того чтобы увидеть заголовок ответа в запрос curl, добавим ключ :

Заголовок будет включен над телом ответа:

Чтобы в ответе получить только заголовок, используем ключ

Заголовок содержит метаданные ответа. Вся эта информация передается в браузер при запросе URL в нашем браузере (например, при просмотре веб-страницы в Интернете), но браузер не отображает эту информацию. Можно просмотреть информацию заголовка с помощью консоли Chrome Developer Tools, перейдя на вкладку .

Теперь давайте уточним метод. Метод GET (чтение) подразумевается по умолчанию, когда не указан другой метод, но мы сделаем это здесь явно с параметром -X:


При посещении веб-сайта мы отправляем запрос, используя метод GET. Существуют и другие методы HTTP, которые можно использовать при взаимодействии с REST API. Вот общие методы, используемые при работе с конечными точками REST:

HTTP метод Описание
POST Создание ресурса
GET Чтение (получение) ресурса
PUT Обновление ресурса
DELETE Удаление ресурса

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

👨‍💻 Опрос

Проверьте свою внимательность. Что означают следующие параметры?

Tip: Использование curl в Терминале или iTerm OS Mac обеспечивают намного более простую работу, чем использование командной строки в Windows. Если серьезно относиться к документации API, работая на ПК, стоит подумать о переходе с OS Windows. Будет много утилит, которые мы установим при помощи Терминала, который просто работает на Mac. Кроме того, находясь в Силиконовой долине, и используя ПК вместо Mac можно показаться старомодным для окружающих (см. Почему большинство стартапов покупают MacBook для своих сотрудников).

Для более подробного изучения curl в документировании REST API можно посмотреть REST-esting with curl.

Строки запроса и параметры

Параметры почтового индекса (), идентификатора приложения () и единиц () были переданы в конечную точку с помощью «строк запроса». Знак добавленный к URL указывает начало строки запроса. Параметры строки запроса — это параметры, которые появляются после знака :

После строки запроса каждый параметр объединяется с другими параметрами через символ амперсанда . Порядок параметров в строке запроса не имеет значения. Порядок имеет значение только в том случае, если параметры находятся слева от строки запроса (и, следовательно, являются частью самого URL-адреса). Любые настраиваемые части конечной точки, которые появляются перед строкой запроса, называются (разберем их позже).

Environment Variables

Curl reads and understands the following environment variables:

They should be set for protocol-specific proxies. General proxy should be set with

A comma-separated list of host names that shouldn’t go through any proxy is set in (only an asterisk, matches all hosts)

If the host name matches one of these strings, or the host is within the domain of one of these strings, transactions with that node will not be proxied. When a domain is used, it needs to start with a period. A user can specify that both www.example.com and foo.example.com should not use a proxy by setting to . By including the full name you can exclude specific host names, so to make not use a proxy but still have do it, set to .

The usage of the / flag overrides the environment variables.

Конвертируем валюту с помощью cURl и Google

Пересчет валюты достаточно простое дело, но курсы достаточно часто изменяются, поэтому приходится использовать сервисы, подобные Google, для получения текущих значений курса пересчета. Функция получает 3 параметра: исходная валюта, целевая валюта и сумма.

function currency($from_Currency,$to_Currency,$amount) {
    $amount = urlencode($amount);
    $from_Currency = urlencode($from_Currency);
    $to_Currency = urlencode($to_Currency);
    $url = "http://www.google.com/ig/calculator?hl=en&q=$amount$from_Currency=?$to_Currency";
    $ch = curl_init();
    $timeout = 0;
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch,  CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $rawdata = curl_exec($ch);
    curl_close($ch);
    $data = explode('"', $rawdata);
    $data = explode(' ', $data);
    $var = $data;
    return round($var,2);
}

Progress Meter

The progress meter exists to show a user that something actually is happening. The different fields in the output have the following meaning:

From left-to-right:

  • % — percentage completed of the whole transfer
  • Total — total size of the whole expected transfer
  • % — percentage completed of the download
  • Received — currently downloaded amount of bytes
  • % — percentage completed of the upload
  • Xferd — currently uploaded amount of bytes
  • Average Speed Dload — the average transfer speed of the download
  • Average Speed Upload — the average transfer speed of the upload
  • Time Total — expected time to complete the operation
  • Time Current — time passed since the invoke
  • Time Left — expected time left to completion
  • Curr.Speed — the average transfer speed the last 5 seconds (the first 5 seconds of a transfer is based on less time of course.)

The option will display a totally different progress bar that doesn’t need much explanation!

FTP and Firewalls

The FTP protocol requires one of the involved parties to open a second connection as soon as data is about to get transferred. There are two ways to do this.

The default way for curl is to issue the PASV command which causes the server to open another port and await another connection performed by the client. This is good if the client is behind a firewall that doesn’t allow incoming connections.

If the server, for example, is behind a firewall that doesn’t allow connections on ports other than 21 (or if it just doesn’t support the command), the other way to do it is to use the command and instruct the server to connect to the client on the given IP number and port (as parameters to the PORT command).

The flag to curl supports a few different options. Your machine may have several IP-addresses and/or network interfaces and curl allows you to select which of them to use. Default address can also be used:

Download with but use the IP address of our interface (this does not work on windows):

Download with but use 192.168.0.10 as our IP address to use:

Simple Usage

Get the main page from Netscape’s web-server:

Get the README file the user’s home directory at funet’s ftp-server:

Get a web page from a server using port 8000:

Get a directory listing of an FTP site:

Get the definition of curl from a dictionary:

Fetch two documents at once:

Get a file off an FTPS server:

or use the more appropriate FTPS way to get the same file:


Get a file from an SSH server using SFTP:

Get a file from an SSH server using SCP using a private key (not password-protected) to authenticate:

Get a file from an SSH server using SCP using a private key (password-protected) to authenticate:

Get the main page from an IPv6 web server:

Get a file from an SMB server:

HTTPS

Secure HTTP requires a TLS library to be installed and used when curl is built. If that is done, curl is capable of retrieving and posting documents using the HTTPS protocol.

Example:

curl is also capable of using client certificates to get/post files from sites that require valid certificates. The only drawback is that the certificate needs to be in PEM-format. PEM is a standard and open format to store certificates with, but it is not used by the most commonly used browsers. If you want curl to use the certificates you use with your (favourite) browser, you may need to download/compile a converter that can convert your browser’s formatted certificates to PEM formatted ones.

Example on how to automatically retrieve a document using a certificate with a personal password:

If you neglect to specify the password on the command line, you will be prompted for the correct password before any data can be received.

Many older HTTPS servers have problems with specific SSL or TLS versions, which newer versions of OpenSSL etc use, therefore it is sometimes useful to specify what SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL version to use (for SSLv3, SSLv2 or TLSv1 respectively):

Otherwise, curl will attempt to use a sensible TLS default version.

Проверяем доступность определённого веб сайта

Как узнать, доступен ли определённый веб сайт? cURL поможет ответить на данный вопрос. Данный скрипт можно использовать совместно с планировщиком для мониторинга сайта.

Замените URL в строке 3 на тот, который вам нужен.  Скопируйте код на свою страницу, и станет известно, доступен ли указанный сайт.

<?php

       if (isDomainAvailible('http://www.ruseller.com'))
       {
               echo "Работает и готов отвечать на запросы!";
       }
       else
       {
               echo "Ой, сайт не доступен.";
       }

       //Возвращает true, если домен доступен
       function isDomainAvailible($domain)
       {
               //Проверка на правильность URL 
               if(!filter_var($domain, FILTER_VALIDATE_URL))
               {
                       return false;
               }

               //Инициализация curl
               $curlInit = curl_init($domain);
               curl_setopt($curlInit,CURLOPT_CONNECTTIMEOUT,10);
               curl_setopt($curlInit,CURLOPT_HEADER,true);
               curl_setopt($curlInit,CURLOPT_NOBODY,true);
               curl_setopt($curlInit,CURLOPT_RETURNTRANSFER,true);

               //Получаем ответ
               $response = curl_exec($curlInit);

               curl_close($curlInit);

               if ($response) return true;

               return false;
       }
?>

Загружаем и сохраняем изображения со страницы с помощью 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;
}

Uploading

FTP / FTPS / SFTP / SCP

Upload all data on stdin to a specified server:

Upload data from a specified file, login with user and password:

Upload a local file to the remote site, and use the local file name at the remote site too:

Upload a local file to get appended to the remote file:

Curl also supports ftp upload through a proxy, but only if the proxy is configured to allow that kind of tunneling. If it does, you can run curl in a fashion similar to:

HTTP

Upload all data on stdin to a specified HTTP site:

Note that the HTTP server must have been configured to accept PUT before this can be done successfully.

For other ways to do HTTP data upload, see the POST section below.

Пару слов о других полезных опциях 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);

}

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


С этим читают