PHP cURL - working with cURL library in PHP (2025)

last modified January 10, 2023

PHP cURL tutorial shows how to work with cURL library in PHP. cURL is a wrapperover the libcurl library.

$ php -vphp -vPHP 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 withURL. 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 isphp-curl.

PHP cURL GET request

In the following examples, we create simple GET requests.

get_req.php

<?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 directlyshown in the standard output.

$ch = curl_init('http://webcode.me');

The curl_init function initializes a new session and returns a cURLhandle for use with the curl_setopt, curl_exec,and curl_close functions. We provice a URL to which we sent therequest.

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.

get_req2.php

<?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. TheCURLOPT_RETURNTRANSFER returns the transfer as a string of thereturn value of curl_exec instead of outputting it directly.

PHP cURL download file

The CURLOPT_FILE option specifies where the transfer should bewritten to; the default is the standard output.

download_file.php

<?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, thatwe have created. With the CURLOPT_HEADER, we disable the header.

PHP cURL HEAD request

A HEAD request is a GET request without the body.

head_req.php

<?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_HEADERto true and the CURLOPT_NOBODY to false. We set all the optionsat once with curl_setopt_array.

$ php head_req.php HTTP/1.1 200 OKServer: nginx/1.6.2Date: Mon, 08 Feb 2021 16:00:24 GMTContent-Type: text/htmlContent-Length: 348Last-Modified: Sat, 20 Jul 2019 11:49:25 GMTConnection: keep-aliveETag: "5d32ffc5-15c"Accept-Ranges: bytes

PHP cURL status code

With the curl_getinfo function we get information regarding aspecific transfer.

status.php

<?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 thestatus by passing the CURLINFO_RESPONSE_CODE option to thecurl_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 andvalues URL-encoded as the request body. The Content-Type header is set toapplication/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.

post_form.php

<?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 POSTfields 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.

post_json.php

<?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 theappropriate 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, whichallows 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 = [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 theirstatus 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 withcurl_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 200200200200----------------------HTTP/1.1 200 OKServer: nginx/1.6.2Date: Mon, 08 Feb 2021 16:37:31 GMTContent-Type: text/htmlContent-Length: 348Last-Modified: Sat, 20 Jul 2019 11:49:25 GMTConnection: keep-aliveETag: "5d32ffc5-15c"Accept-Ranges: bytes----------------------HTTP/2 200 content-encoding: gzipaccept-ranges: bytesage: 285367cache-control: max-age=604800content-type: text/html; charset=UTF-8date: Mon, 08 Feb 2021 16:36:11 GMTetag: "3147526947"expires: Mon, 15 Feb 2021 16:36:11 GMTlast-modified: Thu, 17 Oct 2019 07:18:26 GMTserver: ECS (dcb/7F83)x-cache: HITcontent-length: 648----------------------HTTP/1.1 200 OKDate: Mon, 08 Feb 2021 16:36:11 GMTContent-Type: text/html; charset=utf-8Content-Length: 9593Connection: keep-aliveServer: gunicorn/19.9.0Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true----------------------HTTP/2 200 server: Combust/Plack (Perl)content-type: text/html; charset=utf-8last-modified: Mon, 08 Feb 2021 15:29:36 GMTx-content-type-options: nosniffx-frame-options: denyx-xss-protection: 1strict-transport-security: max-age=15768000via: 1.1 varnish, 1.1 varnishaccept-ranges: bytesdate: Mon, 08 Feb 2021 16:36:11 GMTage: 2713x-served-by: cache-lga21948-LGA, cache-vie21642-VIEx-cache: HIT, HITx-cache-hits: 2, 1x-timer: S1612802172.507868,VS0,VE1content-length: 12011

PHP cURL send email

We build a custom request with the CURLOPT_CUSTOMREQUEST option.

send_mail

<?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 ona LAN.

curl_setopt($ch, CURLOPT_PORT, 25);curl_setopt($ch, CURLOPT_CRLF, true);

We specify the port number with CURLOPT_PORT. TheCURLOPT_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 2021Return-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.comMessage-Id: <202102091700.119H08go001746@core9>To: undisclosed-recipients:;Status: ROHelloHello there

We check the email with an email client on the server.

In this article we have worked with the PHP cURL library.

Author

My name is Jan Bodnar and I am a passionate programmer with many years ofprogramming experience. I have been writing programming articles since 2007. Sofar, I have written over 1400 articles and 8 e-books. I have over eight years ofexperience in teaching programming.

List all PHP tutorials.

PHP cURL - working with cURL library in PHP (2025)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Fredrick Kertzmann

Last Updated:

Views: 6462

Rating: 4.6 / 5 (66 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Fredrick Kertzmann

Birthday: 2000-04-29

Address: Apt. 203 613 Huels Gateway, Ralphtown, LA 40204

Phone: +2135150832870

Job: Regional Design Producer

Hobby: Nordic skating, Lacemaking, Mountain biking, Rowing, Gardening, Water sports, role-playing games

Introduction: My name is Fredrick Kertzmann, I am a gleaming, encouraging, inexpensive, thankful, tender, quaint, precious person who loves writing and wants to share my knowledge and understanding with you.