CURLRequest 类
The CURLRequest 类是一个基于 CURL 的轻量级 HTTP 客户端,允许您与其他网站和服务器进行通信。它可以用于获取 Google 搜索的内容,检索网页或图像,或与 API 通信,以及许多其他事情。
此类是根据 Guzzle HTTP 客户端 库建模的,因为它是使用最广泛的库之一。在可能的情况下,语法保持一致,因此如果您的应用程序需要比此库提供的功能更强大的功能,您只需进行很少的更改即可迁移到使用 Guzzle。
注意
此类需要在您的 PHP 版本中安装 cURL 库。这是一个非常常见的库,通常可用,但并非所有主机都提供它,因此如果您遇到问题,请与您的主机联系以确认。
CURLRequest 配置
加载库
库可以通过手动方式或通过 服务类 加载。
要使用服务类加载,请调用 curlrequest() 方法。
<?php
$client = \Config\Services::curlrequest();
您可以将默认选项数组作为第一个参数传递,以修改 cURL 处理请求的方式。这些选项将在本文档的后面部分进行描述。
<?php
$options = [
'baseURI' => 'http://example.com/api/v1/',
'timeout' => 3,
];
$client = \Config\Services::curlrequest($options);
注意
当 $shareOptions 为 false 时,传递给类构造函数的默认选项将用于所有请求。其他选项将在发送请求后重置。
在手动创建类时,您需要传入一些依赖项。第一个参数是 Config\App 类的实例。第二个参数是 URI 实例。第三个参数是 Response 对象。第四个参数是可选的默认 $options 数组。
<?php
$client = new \CodeIgniter\HTTP\CURLRequest(
new \Config\App(),
new \CodeIgniter\HTTP\URI(),
new \CodeIgniter\HTTP\Response(new \Config\App()),
$options
);
使用库
使用 CURL 请求只需创建请求并获取 Response 对象。它旨在处理通信。之后,您可以完全控制如何处理信息。
发出请求
大多数通信都是通过 request() 方法完成的,该方法会发出请求,然后返回一个 Response 实例。它将 HTTP 方法、URL 和选项数组作为参数。
<?php
$client = \Config\Services::curlrequest();
$response = $client->request('GET', 'https://api.github.com/user', [
'auth' => ['user', 'pass'],
]);
重要
默认情况下,如果返回的 HTTP 代码大于或等于 400,CURLRequest 将抛出 HTTPException。如果您想获取响应,请参阅 http_errors 选项。
注意
当 $shareOptions 为 false 时,传递给方法的选项将用于请求。发送请求后,它们将被清除。如果您想将选项用于所有请求,请在构造函数中传递选项。
由于响应是 CodeIgniter\HTTP\Response 的实例,因此您可以使用所有正常的信息。
<?php
echo $response->getStatusCode();
echo $response->getBody();
echo $response->header('Content-Type');
$language = $response->negotiateLanguage(['en', 'fr']);
虽然 request() 方法是最灵活的,但您也可以使用以下快捷方法。它们都将 URL 作为第一个参数,将选项数组作为第二个参数。
<?php
$client->get('http://example.com');
$client->delete('http://example.com');
$client->head('http://example.com');
$client->options('http://example.com');
$client->patch('http://example.com');
$client->put('http://example.com');
$client->post('http://example.com');
基本 URI
可以在类实例化期间将 baseURI 设置为选项之一。这允许您设置基本 URI,然后使用该客户端使用相对 URL 发出所有请求。这在使用 API 时特别有用。
<?php
$client = \Config\Services::curlrequest([
'baseURI' => 'https://example.com/api/v1/',
]);
// GET http:example.com/api/v1/photos
$client->get('photos');
// GET http:example.com/api/v1/photos/13
$client->delete('photos/13');
当向 request() 方法或任何快捷方法提供相对 URI 时,它将根据 RFC 2986,第 2 节 中描述的规则与 baseURI 相结合。为了节省您的时间,以下是一些关于组合如何解析的示例。
baseURI
URI
结果
http://foo.com
/bar
http://foo.com/bar
http://foo.com/foo
/bar
http://foo.com/bar
http://foo.com/foo
bar
http://foo.com/bar
http://foo.com/foo/
bar
http://foo.com/foo/bar
http://foo.com
http://baz.com
http://baz.com
http://foo.com/?bar
bar
http://foo.com/bar
使用响应
每个 request() 调用都返回一个 Response 对象,其中包含许多有用的信息和一些有用的方法。最常用的方法可以让您确定响应本身。
您可以获取响应的状态代码和原因短语
<?php
$code = $response->getStatusCode(); // 200
$reason = $response->getReason(); // OK
您可以从响应中检索标头
<?php
// Get a header line
echo $response->getHeaderLine('Content-Type');
// Get all headers
foreach ($response->headers() as $name => $value) {
echo $name . ': ' . $response->getHeaderLine($name) . "\n";
}
可以使用 getBody() 方法检索主体
<?php
$body = $response->getBody();
主体是远程服务器提供的原始主体。如果内容类型需要格式化,您需要确保您的脚本处理它。
<?php
if (strpos($response->header('content-type'), 'application/json') !== false) {
$body = json_decode($body);
}
请求选项
本节描述了您可以传递给构造函数、request() 方法或任何快捷方法的所有可用选项。
allow_redirects
默认情况下,cURL 将遵循远程服务器发回的所有“Location:” 标头。 allow_redirects 选项允许您修改其工作方式。
如果将值设置为 false,则它将完全不遵循任何重定向。
<?php
$client->request('GET', 'http://example.com', ['allow_redirects' => false]);
将其设置为 true 将将默认设置应用于请求。
<?php
$client->request('GET', 'http://example.com', ['allow_redirects' => true]);
/*
* Sets the following defaults:
* 'max' => 5, // Maximum number of redirects to follow before stopping
* 'strict' => true, // Ensure POST requests stay POST requests through redirects
* 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols
*/
您可以将数组作为 allow_redirects 选项的值传递,以指定新的设置来代替默认设置。
<?php
$client->request('GET', 'http://example.com', ['allow_redirects' => [
'max' => 10,
'protocols' => ['https'], // Force HTTPS domains only.
]]);
注意
当 PHP 处于 safe_mode 或 open_basedir 启用时,重定向不起作用。
auth
允许您为 HTTP Basic 和 Digest 身份验证提供身份验证详细信息。您的脚本可能需要做额外的工作来支持 Digest 身份验证 - 这只是为您传递用户名和密码。该值必须是一个数组,其中第一个元素是用户名,第二个是密码。第三个参数应该是要使用的身份验证类型,可以是 basic 或 digest
<?php
$client->request('GET', 'http://example.com', ['auth' => ['username', 'password', 'digest']]);
body
对于支持请求主体类型的请求,例如 PUT 或 POST,有两种方法可以设置请求主体。第一种方法是使用 setBody() 方法
<?php
$client->setBody($body)->request('put', 'http://example.com');
第二种方法是传入一个 body 选项。这是为了保持 Guzzle API 的兼容性,并且与前面的示例的功能完全相同。该值必须是字符串
<?php
$client->request('put', 'http://example.com', ['body' => $body]);
cert
要指定 PEM 格式的客户端证书的位置,请将包含文件完整路径的字符串作为 cert 选项的值传递。如果需要密码,请将该值设置为一个数组,第一个元素是证书的路径,第二个元素是密码
<?php
$client->request('get', '/', ['cert' => ['/path/server.pem', 'password']]);
connect_timeout
默认情况下,CodeIgniter 不会对 cURL 连接到网站的尝试设置限制。如果需要修改此值,可以通过 connect_timeout 选项传递以秒为单位的时间量来实现。可以传递 0 表示无限期等待
<?php
$client->request('GET', 'http://example.com', ['connect_timeout' => 0]);
debug
当传递 debug 并将其设置为 true 时,这将启用额外的调试信息,并在脚本执行期间回显到 STDERR。
这是通过传递 CURLOPT_VERBOSE 并回显输出完成的。因此,当通过 spark serve 运行内置服务器时,您将在控制台中看到输出。否则,输出将写入服务器的错误日志。
<?php
$client->request('GET', 'http://example.com', ['debug' => true]);
可以将文件名作为 debug 的值传递,以便将输出写入文件
<?php
$client->request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']);
delay
允许您在发送请求之前暂停一定数量的毫秒
<?php
// Delay for 2 seconds
$client->request('GET', 'http://example.com', ['delay' => 2000]);
form_params
您可以通过在 form_params 选项中传递一个关联数组,在 application/x-www-form-urlencoded POST 请求中发送表单数据。这将设置 Content-Type 头部为 application/x-www-form-urlencoded,如果它尚未设置。
<?php
$client->request('POST', '/post', [
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there'],
],
]);
注意
form_params 不能与 multipart 选项一起使用。您需要使用其中一个。使用 form_params 用于 application/x-www-form-urlencoded 请求,使用 multipart 用于 multipart/form-data 请求。
headers
虽然您可以使用 setHeader() 方法设置此请求所需的任何头部,但您也可以将头部关联数组作为选项传递。每个键都是一个头部的名称,每个值都是一个字符串或字符串数组,表示头部字段值。
<?php
$client->request('get', '/', [
'headers' => [
'User-Agent' => 'testing/1.0',
'Accept' => 'application/json',
'X-Foo' => ['Bar', 'Baz'],
],
]);
如果头部传递到构造函数中,它们将被视为默认值,这些默认值将在以后被任何进一步的头部数组或对 setHeader() 的调用覆盖。
http_errors
默认情况下,CURLRequest 如果返回的 HTTP 代码大于或等于 400,将抛出 HTTPException。
如果您想查看响应主体,可以将 http_errors 设置为 false 以返回内容。
<?php
$client->request('GET', '/status/500');
// If the response code is 500, an HTTPException is thrown,
// and a detailed error report is displayed if in development mode.
$response = $client->request('GET', '/status/500', ['http_errors' => false]);
echo $response->getStatusCode(); // 500
echo $response->getBody(); // You can see the response body.
json
使用 json 选项可以轻松地将 JSON 编码的数据作为请求主体上传。它会添加一个 application/json 的 Content-Type 头,覆盖任何可能已经设置的 Content-Type。提供给此选项的数据可以是 json_encode() 接受的任何值。
<?php
$response = $client->request('PUT', '/put', ['json' => ['foo' => 'bar']]);
注意
此选项不允许对 json_encode() 函数或 Content-Type 头进行任何自定义。如果您需要这种功能,则需要手动编码数据,通过 CURLRequest 的 setBody() 方法传递它,并使用 setHeader() 方法设置 Content-Type 头。
multipart
当您需要通过 POST 请求发送文件和其他数据时,可以使用 multipart 选项以及 CURLFile 类。这些值应该是一个关联数组,包含要发送的 POST 数据。为了更安全的使用,通过在文件名之前添加 @ 来上传文件的传统方法已被禁用。您要发送的任何文件都必须作为 CURLFile 的实例传递。
<?php
$post_data = [
'foo' => 'bar',
'userfile' => new \CURLFile('/path/to/file.txt'),
];
注意
multipart 不能与 form_params 选项一起使用。您只能使用其中一个。对于 application/x-www-form-urlencoded 请求,使用 form_params,对于 multipart/form-data 请求,使用 multipart。
proxy
版本 4.4.0 中的新功能。
您可以通过将关联数组作为 proxy 选项传递来设置代理。
<?php
$client->request(
'GET',
'http://example.com',
['proxy' => 'https://:3128']
);
查询
您可以通过传递一个关联数组作为 query 选项来传递数据作为查询字符串变量。
<?php
// Send a GET request to /get?foo=bar
$client->request('GET', '/get', ['query' => ['foo' => 'bar']]);
超时
默认情况下,cURL 函数可以无限期运行,没有时间限制。您可以使用 timeout 选项修改此行为。该值应为希望函数执行的秒数。使用 0 表示无限期等待。
<?php
$client->request('GET', 'http://example.com', ['timeout' => 5]);
用户代理
允许指定请求的用户代理。
<?php
$client->request('GET', 'http://example.com', ['user_agent' => 'CodeIgniter Framework v4']);
验证
此选项描述 SSL 证书验证行为。如果 verify 选项为 true,则启用 SSL 证书验证并使用操作系统提供的默认 CA 捆绑包。如果设置为 false,则会禁用证书验证(这很不安全,并且允许中间人攻击!)。您可以将其设置为包含 CA 捆绑包路径的字符串,以使用自定义证书启用验证。默认值为 true。
<?php
// Use the system's CA bundle (this is the default setting)
$client->request('GET', '/', ['verify' => true]);
// Use a custom SSL certificate on disk.
$client->request('GET', '/', ['verify' => '/path/to/cert.pem']);
// Disable validation entirely. (Insecure!)
$client->request('GET', '/', ['verify' => false]);
版本
要设置要使用的 HTTP 协议,您可以传递一个包含版本号的字符串或浮点数(通常是 1.0 或 1.1,2.0 从 v4.3.0 开始支持)。
<?php
// Force HTTP/1.0
$client->request('GET', '/', ['version' => 1.0]);