php curl详解及完整的一个curl类库
目录
一、cUrl详解
PHP 中使用 cURL
的更详细说明,包括各种高级用法、错误处理、文件上传、认证、以及更多的示例。
1. 初始化 cURL 会话
curl_init()
用于初始化一个新的 cURL 会话并返回一个 cURL 句柄:
$ch = curl_init();
2. 设置 cURL 选项
使用 curl_setopt()
来设置不同的选项。以下是一些常用选项及其解释:
-
CURLOPT_URL: 设置请求的 URL。
curl_setopt($ch, CURLOPT_URL, "https://example.com");
-
CURLOPT_RETURNTRANSFER: 返回响应内容,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
CURLOPT_POST: 发送 POST 请求。
curl_setopt($ch, CURLOPT_POST, true);
-
CURLOPT_POSTFIELDS: 发送的 POST 数据。
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('key1' => 'value1', 'key2' => 'value2')));
-
CURLOPT_HTTPHEADER: 设置自定义请求头。
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer your-token-here'));
-
CURLOPT_USERAGENT: 设置用户代理字符串。
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; PHP cURL)");
-
CURLOPT_TIMEOUT: 设置请求的超时时间(秒)。
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
-
CURLOPT_FOLLOWLOCATION: 是否跟随重定向。
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
3. 执行 cURL 会话并获取响应
使用 curl_exec()
执行会话并获取响应内容:
$response = curl_exec($ch);
4. 错误处理
使用 curl_errno()
和 curl_error()
检查和获取错误信息:
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
}
5. 关闭 cURL 会话
完成后,使用 curl_close()
关闭 cURL 会话:
curl_close($ch);
GET 请求示例
这是一个完整的 GET 请求并处理响应和错误:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
curl_close($ch);
POST 请求示例
这是一个完整的 POST 请求示例,包括发送数据和处理响应:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('key1' => 'value1', 'key2' => 'value2')));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
curl_close($ch);
文件上传示例
以下是如何通过 cURL
上传文件的示例:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/upload");
curl_setopt($ch, CURLOPT_POST, true);
$file = new CURLFile('/path/to/your/file.jpg', 'image/jpeg', 'file.jpg');
$data = array('file' => $file);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
curl_close($ch);
设置请求头
你可以使用 CURLOPT_HTTPHEADER
来设置自定义请求头:
$headers = array(
'Content-Type: application/json',
'Authorization: Bearer your-token-here'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
GET 请求带参数示例
使用查询字符串发送 GET 请求参数:
$params = array(
'param1' => 'value1',
'param2' => 'value2'
);
$url = "https://example.com?" . http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
curl_close($ch);
处理响应
获取 HTTP 状态码和响应头:
// 获取 HTTP 状态码
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 获取所有响应头
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
$headers = curl_exec($ch);
// 关闭会话
curl_close($ch);
// 输出状态码和响应头
echo "HTTP Code: $http_code\n";
echo "Headers: $headers";
带有认证的请求
Basic Auth
curl_setopt($ch, CURLOPT_USERPWD, "username:password");
Bearer Token
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer your-token-here'));
高级示例:完整的错误处理
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
$error_msg = curl_error($ch);
echo 'Curl error: ' . $error_msg;
} else {
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 200) {
echo 'Response: ' . $response;
} else {
echo "HTTP Error: $http_code\n";
}
}
curl_close($ch);
设置代理
如果需要通过代理发送请求:
curl_setopt($ch, CURLOPT_PROXY, 'http://proxyserver:port');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'username:password');
设置 SSL 选项
如果需要处理 SSL/TLS 证书:
// 不验证证书
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// 设置 CA 证书路径
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
带有 Cookies 的请求
如果需要在请求中包含 Cookies:
curl_setopt($ch, CURLOPT_COOKIE, "name1=value1; name2=value2");
二、完整类库
当然,以下是添加了详细注释的 PHP cURL
类库,包括对 cURL
选项的注释:
<?php
class CurlRequest
{
private $ch; // cURL 句柄
private $response; // cURL 响应内容
private $error; // cURL 错误信息
private $httpCode; // HTTP 状态码
private $headers; // 请求头数组
/**
* 构造函数,初始化 cURL 会话和请求头数组
*/
public function __construct()
{
$this->ch = curl_init();
$this->headers = [];
}
/**
* 设置 cURL 选项
*
* @param array $options cURL 选项数组
*/
private function setOptions(array $options)
{
curl_setopt_array($this->ch, $options);
}
/**
* 设置自定义请求头
*
* @param array $headers 请求头数组
* @return $this 当前实例
*/
public function setHeaders(array $headers)
{
$this->headers = $headers;
return $this;
}
/**
* 发送 GET 请求
*
* @param string $url 请求的 URL
* @return $this 当前实例
*/
public function get($url)
{
$options = [
CURLOPT_URL => $url, // 请求的 URL
CURLOPT_RETURNTRANSFER => true, // 将响应结果返回为字符串,而不是直接输出
CURLOPT_HTTPHEADER => $this->headers, // 自定义请求头
CURLOPT_FOLLOWLOCATION => true, // 启用时会将服务器返回的 "Location: " 放在 header 中递归的返回给服务器
];
$this->setOptions($options);
$this->execute();
return $this;
}
/**
* 发送 POST 请求
*
* @param string $url 请求的 URL
* @param array $data 发送的 POST 数据
* @param bool $json 是否以 JSON 格式发送数据
* @return $this 当前实例
*/
public function post($url, $data = [], $json = false)
{
$options = [
CURLOPT_URL => $url, // 请求的 URL
CURLOPT_POST => true, // 启用 POST 请求
CURLOPT_RETURNTRANSFER => true, // 将响应结果返回为字符串,而不是直接输出
CURLOPT_HTTPHEADER => $this->headers, // 自定义请求头
CURLOPT_FOLLOWLOCATION => true, // 启用时会将服务器返回的 "Location: " 放在 header 中递归的返回给服务器
];
if ($json) {
$options[CURLOPT_POSTFIELDS] = json_encode($data); // 发送 JSON 数据
$this->headers[] = 'Content-Type: application/json'; // 设置请求头为 JSON
} else {
$options[CURLOPT_POSTFIELDS] = http_build_query($data); // 发送表单数据
}
$this->setOptions($options);
$this->execute();
return $this;
}
/**
* 上传文件
*
* @param string $url 请求的 URL
* @param string $filePath 上传文件的路径
* @param string|null $fileName 上传文件的名称
* @param string $fieldName 表单字段名称
* @return $this 当前实例
* @throws Exception 如果文件不存在
*/
public function upload($url, $filePath, $fileName = null, $fieldName = 'file')
{
if (!file_exists($filePath)) {
throw new Exception('File does not exist: ' . $filePath);
}
$file = new CURLFile($filePath);
if ($fileName) {
$file->setPostFilename($fileName);
}
$data = [$fieldName => $file];
$options = [
CURLOPT_URL => $url, // 请求的 URL
CURLOPT_POST => true, // 启用 POST 请求
CURLOPT_POSTFIELDS => $data, // 发送的文件数据
CURLOPT_RETURNTRANSFER => true, // 将响应结果返回为字符串,而不是直接输出
CURLOPT_HTTPHEADER => $this->headers, // 自定义请求头
CURLOPT_FOLLOWLOCATION => true, // 启用时会将服务器返回的 "Location: " 放在 header 中递归的返回给服务器
];
$this->setOptions($options);
$this->execute();
return $this;
}
/**
* 设置代理
*
* @param string $proxy 代理地址
* @param string|null $proxyUserPwd 代理的用户名和密码
* @return $this 当前实例
*/
public function setProxy($proxy, $proxyUserPwd = null)
{
$options = [
CURLOPT_PROXY => $proxy, // 设置代理服务器地址
];
if ($proxyUserPwd) {
$options[CURLOPT_PROXYUSERPWD] = $proxyUserPwd; // 设置代理的用户名和密码
}
$this->setOptions($options);
return $this;
}
/**
* 设置 SSL 选项
*
* @param bool $verifyPeer 是否验证对等证书
* @param int $verifyHost 是否验证主机名
* @return $this 当前实例
*/
public function setSSL($verifyPeer = true, $verifyHost = 2)
{
$options = [
CURLOPT_SSL_VERIFYPEER => $verifyPeer, // 是否验证对等证书
CURLOPT_SSL_VERIFYHOST => $verifyHost, // 是否验证主机名
];
$this->setOptions($options);
return $this;
}
/**
* 执行 cURL 请求
*/
private function execute()
{
$this->response = curl_exec($this->ch); // 执行 cURL 请求并获取响应
$this->error = curl_error($this->ch); // 获取 cURL 错误信息
$this->httpCode = curl_getinfo($this->ch, CURLINFO_HTTP_CODE); // 获取 HTTP 状态码
}
/**
* 获取响应内容
*
* @return string|null 响应内容
*/
public function getResponse()
{
return $this->response;
}
/**
* 获取错误信息
*
* @return string|null 错误信息
*/
public function getError()
{
return $this->error;
}
/**
* 获取 HTTP 状态码
*
* @return int HTTP 状态码
*/
public function getHttpCode()
{
return $this->httpCode;
}
/**
* 关闭 cURL 会话
*/
public function close()
{
curl_close($this->ch);
}
}
三、类库使用示例
类库说明
这个类库封装了更复杂的 cURL
操作,提供了以下方法:
setHeaders(array $headers)
: 设置自定义请求头。get($url)
: 发送 GET 请求。post($url, $data = [], $json = false)
: 发送 POST 请求。支持发送 JSON 数据。upload($url, $filePath, $fileName = null, $fieldName = 'file')
: 上传文件。setProxy($proxy, $proxyUserPwd = null)
: 设置代理。setSSL($verifyPeer = true, $verifyHost = 2)
: 设置 SSL 选项。getResponse()
: 获取响应内容。getError()
: 获取错误信息。getHttpCode()
: 获取 HTTP 状态码。close()
: 关闭 cURL 会话。
使用示例
GET 请求示例
$curl = new CurlRequest();
$response = $curl->setHeaders(['Accept: application/json'])
->get("https://jsonplaceholder.typicode.com/posts/1")
->getResponse();
if ($curl->getError()) {
echo "GET Error: " . $curl->getError();
} else {
echo "GET Response: " . $response;
}
$curl->close();
POST 请求示例
$curl = new CurlRequest();
$postData = ['title' => 'foo', 'body' => 'bar', 'userId' => 1];
$response = $curl->setHeaders(['Content-Type: application/json'])
->post("https://jsonplaceholder.typicode.com/posts", $postData, true)
->getResponse();
if ($curl->getError()) {
echo "POST Error: " . $curl->getError();
} else {
echo "POST Response: " . $response;
}
$curl->close();
文件上传示例
$curl = new CurlRequest();
$response = $curl->upload("https://example.com/upload", "/path/to/your/file.jpg", "uploaded_file.jpg")
->getResponse();
if ($curl->getError()) {
echo "Upload Error: " . $curl->getError();
} else {
echo "Upload Response: " . $response;
}
$curl->close();
设置代理示例
$curl = new CurlRequest();
$response = $curl->setProxy('http://proxyserver:port', 'username:password')
->get("https://example.com")
->getResponse();
if ($curl->getError()) {
echo "Proxy Error: " . $curl->getError();
} else {
echo "Proxy Response: " . $response;
}
$curl->close();
设置 SSL 选项示例
$curl = new CurlRequest();
$response = $curl->setSSL(false)
->get("https://self-signed.badssl.com/")
->getResponse();
if ($curl->getError()) {
echo "SSL Error: " . $curl->getError();
} else {
echo "SSL Response: " . $response;
}
$curl->close();
拿上直接用吧宝子