PHPcURL与HTTP请求实战指南
PHP cURL与HTTP请求实战指南PHP的cURL扩展是发送HTTP请求的标准方式。它支持各种协议、认证方式、SSL证书验证等。今天说说cURL的各种用法。先看最基本的GET请求。curl_init初始化一个cURL会话curl_setopt设置选项curl_exec执行请求curl_close关闭会话。php// 基本的GET请求$ch curl_init(https://api.example.com/users);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_TIMEOUT, 30);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);$response curl_exec($ch);$httpCode curl_getinfo($ch, CURLINFO_HTTP_CODE);if (curl_errno($ch)) {echo cURL错误: . curl_error($ch) . \n;} else {echo HTTP状态码: $httpCode\n;echo 响应时间: . curl_getinfo($ch, CURLINFO_TOTAL_TIME) . 秒\n;echo 响应内容: $response\n;}curl_close($ch);?封装一个HTTP客户端方便复用phpclass HttpClient{private array $defaultOptions [CURLOPT_RETURNTRANSFER true,CURLOPT_TIMEOUT 30,CURLOPT_CONNECTTIMEOUT 10,CURLOPT_FOLLOWLOCATION true,CURLOPT_MAXREDIRS 5,CURLOPT_SSL_VERIFYPEER true,CURLOPT_USERAGENT PHP HttpClient/1.0,];private array $headers [];public function setHeader(string $name, string $value): void{$this-headers[$name] $value;}public function setHeaders(array $headers): void{foreach ($headers as $name $value) {$this-headers[$name] $value;}}public function get(string $url, array $query []): array{if (!empty($query)) {$url . (strpos($url, ?) false ? ? : ) . http_build_query($query);}return $this-request(GET, $url);}public function post(string $url, mixed $data []): array{return $this-request(POST, $url, $data);}public function put(string $url, mixed $data []): array{return $this-request(PUT, $url, $data);}public function delete(string $url): array{return $this-request(DELETE, $url);}private function request(string $method, string $url, mixed $data null): array{$ch curl_init($url);$options $this-defaultOptions;// 设置请求方法switch (strtoupper($method)) {case POST:$options[CURLOPT_POST] true;break;case PUT:$options[CURLOPT_CUSTOMREQUEST] PUT;break;case DELETE:$options[CURLOPT_CUSTOMREQUEST] DELETE;break;case HEAD:$options[CURLOPT_NOBODY] true;break;}// 设置请求体if ($data ! null) {if (is_array($data)) {$options[CURLOPT_POSTFIELDS] http_build_query($data);} else {$options[CURLOPT_POSTFIELDS] $data;$this-headers[Content-Type] application/json;}}// 设置请求头if (!empty($this-headers)) {$headerLines [];foreach ($this-headers as $name $value) {$headerLines[] $name: $value;}$options[CURLOPT_HTTPHEADER] $headerLines;}curl_setopt_array($ch, $options);$body curl_exec($ch);$result [body $body,http_code curl_getinfo($ch, CURLINFO_HTTP_CODE),content_type curl_getinfo($ch, CURLINFO_CONTENT_TYPE),total_time curl_getinfo($ch, CURLINFO_TOTAL_TIME),error curl_error($ch),errno curl_errno($ch),];curl_close($ch);return $result;}}// 使用$client new HttpClient();$client-setHeaders([Accept application/json,Authorization Bearer token123,]);$result $client-get(https://jsonplaceholder.typicode.com/posts, [userId 1]);echo 状态码: {$result[http_code]}\n;if ($result[http_code] 200) {$posts json_decode($result[body], true);echo 获取到 . count($posts) . 篇文章\n;}?发送JSON格式的POST请求php$client new HttpClient();$client-setHeader(Content-Type, application/json);$client-setHeader(Accept, application/json);$client-setHeader(Authorization, Bearer your-api-key);$data [title Test Post,body This is a test post body,userId 1,];$result $client-post(https://jsonplaceholder.typicode.com/posts, json_encode($data));echo 状态码: {$result[http_code]}\n;if ($result[http_code] 201) {$response json_decode($result[body], true);echo 创建成功, ID: {$response[id]}\n;}?文件上传用cURL也很方便phpfunction uploadFile(string $url, string $filePath, string $fieldName file): array{if (!file_exists($filePath)) {throw new RuntimeException(文件不存在: $filePath);}$ch curl_init($url);curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER true,CURLOPT_POST true,CURLOPT_POSTFIELDS [$fieldName curl_file_create($filePath, mime_content_type($filePath), basename($filePath)),],CURLOPT_TIMEOUT 60,]);$body curl_exec($ch);$result [body $body,http_code curl_getinfo($ch, CURLINFO_HTTP_CODE),error curl_error($ch),];curl_close($ch);return $result;}// 批量请求function batchRequest(array $requests): array{$multi curl_multi_init();$handles [];foreach ($requests as $id $request) {$ch curl_init($request[url]);curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER true,CURLOPT_TIMEOUT 30,]);if (!empty($request[method] ?? GET)) {curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request[method]);}if (!empty($request[data])) {curl_setopt($ch, CURLOPT_POSTFIELDS, $request[data]);}curl_multi_add_handle($multi, $ch);$handles[$id] $ch;}// 执行所有请求$running null;do {curl_multi_exec($multi, $running);curl_multi_select($multi);} while ($running 0);// 收集结果$results [];foreach ($handles as $id $ch) {$results[$id] [body curl_multi_getcontent($ch),http_code curl_getinfo($ch, CURLINFO_HTTP_CODE),error curl_error($ch),];curl_multi_remove_handle($multi, $ch);curl_close($ch);}curl_multi_close($multi);return $results;}$requests [users [url https://jsonplaceholder.typicode.com/users],posts [url https://jsonplaceholder.typicode.com/posts],comments [url https://jsonplaceholder.typicode.com/comments],];$results batchRequest($requests);foreach ($results as $name $result) {$data json_decode($result[body], true);echo $name: 获取到 . count($data) . 条记录\n;}?cURL还支持SSL验证、代理、Cookie等高级功能phpclass AdvancedHttpClient{private array $options;public function __construct(array $config []){$this-options [CURLOPT_RETURNTRANSFER true,CURLOPT_TIMEOUT $config[timeout] ?? 30,CURLOPT_COOKIEJAR $config[cookie_jar] ?? /tmp/cookies.txt,CURLOPT_COOKIEFILE $config[cookie_file] ?? /tmp/cookies.txt,];// SSL配置if (!empty($config[ssl_cert])) {$this-options[CURLOPT_SSLCERT] $config[ssl_cert];$this-options[CURLOPT_SSLCERTPASSWD] $config[ssl_cert_pass] ?? ;}// 代理配置if (!empty($config[proxy])) {$this-options[CURLOPT_PROXY] $config[proxy];$this-options[CURLOPT_PROXYPORT] $config[proxy_port] ?? 8080;if (!empty($config[proxy_user])) {$this-options[CURLOPT_PROXYUSERPWD] $config[proxy_user] . : . $config[proxy_pass];}}// 认证配置if (!empty($config[auth])) {$this-options[CURLOPT_HTTPAUTH] CURLAUTH_BASIC | CURLAUTH_DIGEST;$this-options[CURLOPT_USERPWD] $config[auth];}}public function download(string $url, string $savePath): bool{$fp fopen($savePath, w);if ($fp false) {throw new RuntimeException(无法写入文件: $savePath);}$ch curl_init($url);curl_setopt_array($ch, $this-options [CURLOPT_FILE $fp,CURLOPT_FOLLOWLOCATION true,]);curl_exec($ch);$httpCode curl_getinfo($ch, CURLINFO_HTTP_CODE);$error curl_error($ch);curl_close($ch);fclose($fp);if ($error) {throw new RuntimeException(下载失败: $error);}return $httpCode 200;}}$downloader new AdvancedHttpClient([timeout 120]);try {$result $downloader-download(https://example.com/file.zip, /tmp/file.zip);echo 下载完成\n;} catch (RuntimeException $e) {echo 错误: {$e-getMessage()}\n;}?cURL的错误处理很关键。常见的错误有超时、连接失败、SSL验证失败等。curl_errno和curl_error可以获取错误信息。phpfunction checkCurlError(int $errno, string $error): string{$errors [CURLE_COULDNT_RESOLVE_HOST 无法解析主机名,CURLE_COULDNT_CONNECT 无法连接服务器,CURLE_OPERATION_TIMEDOUT 请求超时,CURLE_SSL_CONNECT_ERROR SSL连接错误,CURLE_SSL_CERTPROBLEM SSL证书问题,CURLE_HTTP_RETURNED_ERROR HTTP返回错误,CURLE_SEND_ERROR 发送数据失败,CURLE_RECV_ERROR 接收数据失败,];return $errors[$errno] ?? 未知错误($errno): $error;}?cURL在PHP开发中很常用。对接第三方API、抓取网页内容、上传下载文件都离不开它。用好cURL能让你在处理HTTP请求时事半功倍。