本文目录导读:

我来详细介绍PHP中cURL和HTTP请求的使用方法。
cURL基础使用
基本GET请求
// 初始化cURL
$ch = curl_init();
// 设置URL
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/data");
// 返回响应而不是直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 执行请求
$response = curl_exec($ch);
// 检查错误
if(curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
}
// 关闭cURL
curl_close($ch);
POST请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/submit");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
// POST数据
$data = array(
'username' => 'john',
'password' => 'secret123'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
curl_close($ch);
JSON数据POST
$data = array(
'name' => 'John Doe',
'email' => 'john@example.com'
);
$jsonData = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/users");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData)
));
$response = curl_exec($ch);
curl_close($ch);
常用cURL选项
基本配置
$ch = curl_init();
// 超时设置
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30秒超时
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时
// SSL验证
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// 跟随重定向
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
// 自定义User-Agent
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
// 自定义头部
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer your_token_here',
'Accept: application/json'
));
处理Cookie
// 保存cookie到文件
$cookieFile = tempnam('/tmp', 'cookie');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/login");
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
// 登录请求
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=test&password=123');
$response = curl_exec($ch);
// 后续请求会自动携带cookie
curl_setopt($ch, CURLOPT_URL, "https://example.com/dashboard");
$response = curl_exec($ch);
curl_close($ch);
封装cURL函数
通用HTTP请求函数
class HttpClient {
public static function get($url, $headers = []) {
return self::request('GET', $url, null, $headers);
}
public static function post($url, $data = [], $headers = []) {
return self::request('POST', $url, $data, $headers);
}
public static function put($url, $data = [], $headers = []) {
return self::request('PUT', $url, $data, $headers);
}
public static function delete($url, $headers = []) {
return self::request('DELETE', $url, null, $headers);
}
private static function request($method, $url, $data = null, $headers = []) {
$ch = curl_init();
// 基本设置
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
// 设置请求方法
switch ($method) {
case 'POST':
curl_setopt($ch, CURLOPT_POST, true);
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data);
}
break;
case 'PUT':
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? json_encode($data) : $data);
}
break;
case 'DELETE':
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
}
// 设置头部
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return [
'success' => false,
'error' => $error,
'http_code' => $httpCode
];
}
return [
'success' => true,
'data' => $response,
'http_code' => $httpCode
];
}
}
// 使用示例
$result = HttpClient::get('https://api.example.com/users');
$result = HttpClient::post('https://api.example.com/users', ['name' => 'John'], [
'Content-Type: application/json'
]);
文件上传
使用cURL上传文件
function uploadFile($url, $filePath, $fieldName = 'file') {
if (!file_exists($filePath)) {
return ['success' => false, 'error' => 'File not found'];
}
$ch = curl_init();
// PHP 5.5+ 使用 CURLFile
$cFile = new CURLFile($filePath, mime_content_type($filePath), basename($filePath));
$postData = [
$fieldName => $cFile,
// 其他字段
'description' => 'Test upload'
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'success' => $httpCode == 200,
'data' => $response,
'http_code' => $httpCode
];
}
并发请求
使用curl_multi进行并发
function multiRequest($urls) {
$multi = curl_multi_init();
$channels = [];
// 创建多个cURL句柄
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_multi_add_handle($multi, $ch);
$channels[$key] = $ch;
}
// 执行所有请求
$active = null;
do {
$mrc = curl_multi_exec($multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($multi) == -1) {
usleep(100);
}
do {
$mrc = curl_multi_exec($multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
// 获取结果
$results = [];
foreach ($channels as $key => $ch) {
$results[$key] = curl_multi_getcontent($ch);
curl_multi_remove_handle($multi, $ch);
}
curl_multi_close($multi);
return $results;
}
// 使用示例
$urls = [
'google' => 'https://www.google.com',
'github' => 'https://www.github.com',
'php' => 'https://www.php.net'
];
$results = multiRequest($urls);
错误处理和调试
完整的错误处理
function safeCurlRequest($url, $options = []) {
$defaults = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_VERBOSE => true // 启用详细输出用于调试
];
$ch = curl_init();
curl_setopt_array($ch, $defaults + $options);
// 收集调试信息
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
// 错误检查
$error = curl_error($ch);
$errno = curl_errno($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 获取调试信息
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
curl_close($ch);
if ($error) {
return [
'success' => false,
'error' => $error,
'errno' => $errno,
'http_code' => $httpCode,
'verbose' => $verboseLog
];
}
return [
'success' => true,
'data' => $response,
'http_code' => $httpCode,
'info' => curl_getinfo($ch)
];
}
使用Guzzle替代cURL
GuzzleHTTP库示例
// 安装: composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
'base_uri' => 'https://api.example.com',
'timeout' => 30,
'headers' => [
'Accept' => 'application/json',
'User-Agent' => 'MyApp/1.0'
]
]);
// GET请求
try {
$response = $client->get('/users', [
'query' => ['page' => 1, 'limit' => 10]
]);
$body = $response->getBody();
$data = json_decode($body, true);
} catch (RequestException $e) {
if ($e->hasResponse()) {
$statusCode = $e->getResponse()->getStatusCode();
$errorBody = $e->getResponse()->getBody();
}
}
// POST请求
$response = $client->post('/users', [
'json' => [
'name' => 'John',
'email' => 'john@example.com'
]
]);
// 并发请求
$promises = [
'users' => $client->getAsync('/users'),
'posts' => $client->getAsync('/posts'),
];
$results = GuzzleHttp\Promise\Utils::unwrap($promises);
最佳实践
- 使用try-catch:始终包含错误处理
- 设置超时:避免请求挂起
- 验证SSL:生产环境保持启用
- 重用cURL句柄:提高性能
- 记录日志:便于调试
- 使用连接池:大量请求时复用连接
选择cURL还是Guzzle取决于项目需求:
- cURL:更底层,控制更精细
- Guzzle:更现代,功能更丰富,适合复杂场景