ZetCode

PHP cURL

最后修改于 2025 年 2 月 16 日

PHP cURL 教程展示了如何在 PHP 中使用 cURL 库。cURL 是 libcurl 库的封装。

cURL

curl 是一个命令行工具和库,用于通过 URL 传输数据。它支持多种协议,包括 HTTP、HTTPS、FTP、GOPHER、MQTT 或 SMTP。cURL 是一个 PHP 库的封装。

必须安装 cURL。例如,在 Debian 上,软件包名称是 php-curl

PHP cURL GET 请求

在以下示例中,我们创建简单的 GET 请求。

get_req.php
<?php

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

curl_exec($ch);
curl_close($ch);

在这个例子中,我们向一个小型网站发送一个 GET 请求。输出直接显示在标准输出中。

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

curl_init 函数初始化一个新的会话,并返回一个 cURL 句柄,用于 curl_setoptcurl_execcurl_close 函数。我们提供一个 URL,向其发送请求。

curl_exec($ch);

curl_exec 执行给定的 cURL 会话。

curl_close($ch);

curl_close 关闭 cURL 会话。

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

在下一个例子中,我们将传输的输出发送到一个变量中。

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;

通过 curl_setopt,我们为 cURL 传输设置选项。CURLOPT_RETURNTRANSFER 将传输作为 curl_exec 的返回值字符串返回,而不是直接输出。

PHP cURL 下载文件

CURLOPT_FILE 选项指定将传输写入的位置;默认是标准输出。

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

在这个例子中,我们将 CURLOPT_FILE 选项设置为我们创建的文件句柄。通过 CURLOPT_HEADER,我们禁用头部信息。

PHP cURL HEAD 请求

HEAD 请求是一个没有正文的 GET 请求。

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

为了生成一个 HEAD 请求,我们将 CURLOPT_HEADER 设置为 true,将 CURLOPT_NOBODY 设置为 false。我们使用 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 状态码

使用 curl_getinfo 函数,我们可以获取有关特定传输的信息。

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

我们向一个网站发送一个 HEAD 请求。在执行请求之后,我们通过将 CURLINFO_RESPONSE_CODE 选项传递给 curl_getinfo 函数来获取状态。

$ php status.php 
200

PHP cURL POST 表单

POST 表单请求向指定的 URL 发送一个 POST 请求,其中数据的键和值以 URL 编码的形式作为请求正文。Content-Type 头部设置为 application/x-www-form-urlencoded。数据在请求的正文中发送;键和值以键值对元组的形式编码,用 '&' 分隔,键和值之间用 '=' 分隔。

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;

POST 请求通过 CURLOPT_POST 选项设置。POST 字段通过 CURLOPT_POSTFIELDS 选项设置。

$ 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

在以下示例中,我们 POST JSON 数据。

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;

我们使用 json_encode 函数对 JSON 数据进行编码。我们使用 CURLOPT_HTTPHEADER 选项设置适当的头部信息。

$ 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 多个异步请求

curl_multi_init 函数创建一个新的多句柄,允许异步处理多个 cURL 句柄。

multi_async.php
<?php

$urls = [ 
    "http://webcode.me", 
    "https://example.com",
    "http://httpbin.org",
    "https://perl.net.cn"
];

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

在这个例子中,我们向四个网站创建异步请求。我们打印它们的状态码和头部信息。

$mh = curl_multi_init();

我们初始化多句柄。

foreach ($urls as $url) {

    $ch = curl_init($url);
    curl_setopt_array($ch, $options);
    curl_multi_add_handle($mh, $ch);
    $chs[] = $ch;
}

我们为每个 URL 创建标准句柄,并使用 curl_multi_add_handle 将它们添加到多句柄中。

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

我们获取头部信息。

$ 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 发送电子邮件

我们使用 CURLOPT_CUSTOMREQUEST 选项构建一个自定义请求。

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

该示例向本地网络上的计算机发送电子邮件。

$ch = curl_init("core9");

core9 是在 LAN 上运行邮件服务器的计算机的名称。

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

我们使用 CURLOPT_PORT 指定端口号。CURLOPT_CRLF 将 Unix 换行符转换为 \r\n,它们是 SMTP 协议的控制字符。

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

邮件通过使用 SMPT 命令构建。

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

我们在服务器上使用电子邮件客户端检查电子邮件。

来源

cURL - PHP 手册

在本文中,我们使用了 PHP cURL 库。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 PHP 教程。