PHP 使用 cURL

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

$ php -v
php -v
PHP 8.1.2 (cli) (built: Aug  8 2022 07:28:23) (NTS)
...

我们使用PHP版本8.1.2。

卷曲

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

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

PHPcURLGET请求

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

<?php

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

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

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

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

curl_init函数初始化一个新会话并返回一个用于curl_setoptcurl_execcurl_close功能。我们提供一个URL,我们将请求发送到该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>

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

<?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的返回值的字符串返回,而不是直接输出。

PHPcURL下载文件

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

<?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,我们禁用标头。

PHPcURLHEAD请求

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

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

PHPcURL状态码

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

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

PHPcURLPOST表单

POST表单请求向指定的URL发出POST,数据的键和值经过URL编码作为请求主体。Content-Type标头设置为application/x-www-form-urlencoded。数据在请求的正文中发送;键和值被编码在由“&”分隔的键值元组中,键和值之间有一个“=”。

<?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"
}

PHPcURLPOSTJSON

在下面的示例中,我们POSTJSON数据。

<?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"
}

PHPcURL多个异步请求

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

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

在示例中,我们创建了对四个网站的异步请求。我们打印他们的状态代码和标题。

$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

PHPcURL发送邮件

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

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

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

在本教程中,我们使用了PHPcURL库。

列出所有PHP教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏