PHP cURL
last modified January 10, 2023
PHP cURL tutorial shows how to work with cURL library in PHP. cURL is a wrapper over the libcurl library.
$ php -v php -v PHP 8.1.2 (cli) (built: Aug 8 2022 07:28:23) (NTS) ...
We use PHP version 8.1.2.
cURL
The curl
is a command line tool and library for transferring data with
URL. It supports multiple protocols including HTTP, HTTPS, FTP, GOPHER, MQTT,
or SMTP. The cURL
is a PHP wrapper over the library.
The cURL must be installed. For instance, on Debian the package name is
php-curl
.
PHP cURL GET request
In the following examples, we create simple GET requests.
<?php $ch = curl_init('http://webcode.me'); curl_exec($ch); curl_close($ch);
In the example, we send a GET request to a small website. The output is directly shown in the standard output.
$ch = curl_init('http://webcode.me');
The curl_init
function initializes a new session and returns a cURL
handle for use with the curl_setopt
, curl_exec
,
and curl_close
functions. We provice a URL to which we sent the
request.
curl_exec($ch);
The curl_exec
executes the given cURL session.
curl_close($ch);
The curl_close
closes the cURL session.
$ php get_req.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html>
In the next example, we send the output of the transfer to a variable.
<?php $ch = curl_init('http://webcode.me'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); curl_close($ch); echo $data;
With the curl_setopt
we set options for the cURL transfer. The
CURLOPT_RETURNTRANSFER
returns the transfer as a string of the
return value of curl_exec
instead of outputting it directly.
PHP cURL download file
The CURLOPT_FILE
option specifies where the transfer should be
written to; the default is the standard output.
<?php $ch = curl_init('http://webcode.me'); $fp = fopen('index.html', 'w'); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, false); curl_exec($ch); if (curl_error($ch)) { fwrite($fp, curl_error($ch)); } curl_close($ch); fclose($fp);
In the example, we set CURLOPT_FILE
option to a file handle, that
we have created. With the CURLOPT_HEADER
, we disable the header.
PHP cURL HEAD request
A HEAD request is a GET request without the body.
<?php $ch = curl_init('http://webcode.me'); $options = [CURLOPT_HEADER => true, CURLOPT_NOBODY => true, CURLOPT_RETURNTRANSFER => true ]; curl_setopt_array($ch, $options); $data = curl_exec($ch); echo $data; curl_close($ch);
In order to generate a HEAD request, we set the CURLOPT_HEADER
to true and the CURLOPT_NOBODY
to false. We set all the options
at once with curl_setopt_array
.
$ php head_req.php HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Mon, 08 Feb 2021 16:00:24 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
PHP cURL status code
With the curl_getinfo
function we get information regarding a
specific transfer.
<?php $ch = curl_init('http://webcode.me'); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); echo $status; curl_close($ch);
We send a HEAD reqeust to a website. After executing the request, we get the
status by passing the CURLINFO_RESPONSE_CODE
option to the
curl_getinfo
function.
$ php status.php 200
PHP cURL POST form
The POST form request issues a POST to the specified URL, with data's keys and values URL-encoded as the request body. The Content-Type header is set to application/x-www-form-urlencoded. The data is sent in the body of the request; the keys and values are encoded in key-value tuples separated by '&', with a '=' between the key and the value.
<?php $ch = curl_init('http://httpbin.org/post'); $fields = ['name' => 'John Doe', 'occupation' => 'gardener']; $options = [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $fields, CURLOPT_RETURNTRANSFER => true]; curl_setopt_array($ch, $options); $data = curl_exec($ch); curl_close($ch); echo $data;
The POST request is set with the CURLOPT_POST
option. The POST
fields are set with the CURLOPT_POSTFIELDS
option.
$ php post_form.php { "args": {}, "data": "", "files": {}, "form": { "name": "John Doe", "occupation": "gardener" }, "headers": { "Accept": "*/*", "Content-Length": "254", "Content-Type": "multipart/form-data; ... "Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-602162bf-3d24fe793b7403de54ad250f" }, "json": null, ... "url": "http://httpbin.org/post" }
PHP cURL POST JSON
In the following example, we POST JSON data.
<?php $ch = curl_init('http://httpbin.org/post'); $fields = json_encode(['name' => 'John Doe', 'occupation' => 'gardener']); $options = [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $fields, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true]; curl_setopt_array($ch, $options); $data = curl_exec($ch); curl_close($ch); echo $data;
We encode the JSON data with the json_encode
function. We set the
appropriate header with the CURLOPT_HTTPHEADER
option.
$ php post_json.php { "args": {}, "data": "{\"name\":\"John Doe\",\"occupation\":\"gardener\"}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Content-Length": "43", "Content-Type": "application/json", "Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-60216559-2436c3fe055f0fb61eb074d1" }, "json": { "name": "John Doe", "occupation": "gardener" }, ... "url": "http://httpbin.org/post" }
PHP cURL multiple async requests
The curl_multi_init
function creates a new multi handle, which
allows the processing of multiple cURL handles asynchronously.
<?php $urls = [ "http://webcode.me", "https://example.com", "http://httpbin.org", "https://www.perl.org" ]; $options = [CURLOPT_HEADER => true, CURLOPT_NOBODY => true, CURLOPT_RETURNTRANSFER => true]; $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
curl_multi_add_handle
.
$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
PHP cURL send email
We build a custom request with the CURLOPT_CUSTOMREQUEST
option.
<?php $ch = curl_init("core9"); curl_setopt($ch, CURLOPT_PORT, 25); curl_setopt($ch, CURLOPT_CRLF, true); $from = "john.doe@example.com"; $to = "root@core9"; $name = "John Doe"; $subject = "Hello"; $body = "Hello there"; $data = "EHLO core9\n"; $data .= "MAIL FROM:<$from>\n"; $data .= "RCPT TO:<$to>\n"; $data .= "DATA\n"; $data .= "$subject\n"; $data .= "$body\n"; $data .= "\n.\n"; $data .= "QUIT\n"; curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $data); curl_exec($ch); curl_close($ch);
The example sends an email to a computer on a local network.
$ch = curl_init("core9");
The core9
is the name of the computer running email server on
a LAN.
curl_setopt($ch, CURLOPT_PORT, 25); curl_setopt($ch, CURLOPT_CRLF, true);
We specify the port number with CURLOPT_PORT
. The
CURLOPT_CRLF
translates Unix new lines into \r\n
,
which are control characters of the SMTP protocol.
$data = "EHLO core9\n"; $data .= "MAIL FROM:<$from>\n"; $data .= "RCPT TO:<$to>\n"; $data .= "DATA\n"; $data .= "$subject\n"; $data .= "$body\n"; $data .= "\n.\n"; $data .= "QUIT\n";
The mail is build by using the SMPT commands.
From john.doe@example.com Tue Feb 9 18:00:08 2021 Return-Path: <john.doe@example.com> Received: from core9 (spartan.local [192.168.0.20]) by core9 (8.15.2/8.15.2) with ESMTP id 119H08go001746 for <root@core9>; Tue, 9 Feb 2021 18:00:08 +0100 (CET) (envelope-from john.doe@example.com) Date: Tue, 9 Feb 2021 18:00:08 +0100 (CET) From: john.doe@example.com Message-Id: <202102091700.119H08go001746@core9> To: undisclosed-recipients:; Status: RO Hello Hello there
We check the email with an email client on the server.
In this article we have worked with the PHP cURL library.
Author
List all PHP tutorials.