首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP cURL 實戰指南:POST 請求、多線程併發與最佳實踐

     編輯:PHP 相關知識

cURL 是 PHP 中最強大的網絡請求工具,支持 HTTP/HTTPS、FTP、SFTP 等多種協議,提供 SSL 證書、Cookie、代理、斷點續傳等豐富功能。本文通過實戰案例,系統講解 cURL 的 POST 請求、XML/JSON 數據提交、飛信/短信接口調用,以及高性能多線程併發實現。

環境準備:啟用 cURL 擴展

Windows

  1. 編輯 php.ini,取消註釋 extension=php_curl.dll
  2. 將 libeay32.dll、ssleay32.dll、php_curl.dll 複製到系統目錄 C:\Windows\System32
  3. 重啟 Apache/IIS

Linux

# Ubuntu/Debian
sudo apt-get install php-curl
sudo systemctl restart apache2

# CentOS/RHEL
sudo yum install php-curl
sudo systemctl restart httpd

基礎 POST 請求流程

<?php
// 1. 初始化
$ch = curl_init();

// 2. 設置選項
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://api.example.com/endpoint',
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query(['key' => 'value']),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
    CURLOPT_TIMEOUT => 10,
    CURLOPT_SSL_VERIFYPEER => false, // 僅測試環境使用
]);

// 3. 執行請求
$response = curl_exec($ch);

// 4. 錯誤處理
if (curl_errno($ch)) {
    throw new Exception(curl_error($ch), curl_errno($ch));
}

// 5. 關閉資源
curl_close($ch);

// 6. 處理響應
$data = json_decode($response, true);
?>

實戰案例一:XML 數據提交(短信/彩信接口)

<?php
$xml_data = '<?xml version="1.0" encoding="UTF-8"?>
<request>
    <message>測試內容</message>
</request>';

$url = 'https://api.example.com/submit';
$headers = [
    'Content-Type: text/xml; charset=UTF-8',
    'Content-Length: ' . strlen($xml_data)
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $xml_data,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    error_log("cURL Error: " . curl_error($ch));
}
curl_close($ch);

echo $response;
?>

實戰案例二:表單數據提交(飛信/短信接口)

<?php
$postData = [
    'username' => '13800138000',
    'password' => '123456',
    'sendto' => '13912345678',
    'message' => '測試短信內容!'
];

$ch = curl_init('https://sms.api.example.com/send');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($postData),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => false,
    CURLOPT_TIMEOUT => 15,
]);

$result = curl_exec($ch);
curl_close($ch);

var_dump(json_decode($result, true));
?>

高性能多線程併發:curl_multi 詳解

傳統串行請求耗時 = 所有請求耗時之和。多線程併發可將總耗時降為最慢單個請求的耗時,對聚合多個 API、爬蟲、批量推送場景極其關鍵。

封裝類實現

<?php
class CurlMulti {
    public static function request(array $urls, int $timeout = 10): array {
        $handles = [];
        $mh = curl_multi_init();
        $results = [];

        // 初始化所有 handle
        foreach ($urls as $key => $url) {
            $ch = curl_init($url);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => $timeout,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_MAXREDIRS => 5,
                CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP CurlMulti)',
                CURLOPT_HEADER => false,
            ]);
            $handles[$key] = $ch;
            curl_multi_add_handle($mh, $ch);
        }

        // 執行併發請求
        $active = null;
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc === CURLM_CALL_MULTI_PERFORM);

        while ($active && $mrc === CURLM_OK) {
            if (curl_multi_select($mh) !== -1) {
                do {
                    $mrc = curl_multi_exec($mh, $active);
                } while ($mrc === CURLM_CALL_MULTI_PERFORM);
            }
        }

        // 收集結果
        foreach ($handles as $key => $ch) {
            $error = curl_error($ch);
            $results[$key] = [
                'content' => curl_multi_getcontent($ch),
                'info' => curl_getinfo($ch),
                'error' => $error ?: null,
            ];
            curl_multi_remove_handle($mh, $ch);
            curl_close($ch);
        }
        curl_multi_close($mh);

        return $results;
    }
}

// 使用示例
$urls = [
    'https://api.github.com',
    'https://httpbin.org/get',
    'https://jsonplaceholder.typicode.com/posts/1',
];
$results = CurlMulti::request($urls, 10);
print_r($results);
?>

關鍵點解析

  • curl_multi_select:避免 CPU 空轉,等待網絡 I/O 就緒
  • CURLM_CALL_MULTI_PERFORM:表示還有數據待處理,需持續調用 curl_multi_exec
  • 錯誤隔離:單個請求失敗不影響其他請求
  • 超時控制:CURLOPT_TIMEOUT 控制單請求上限,防止阻塞

最佳實踐總結

場景建議設置
第三方 API 調用設置合理超時、啟用 SSL 驗證、記錄請求日志
高併發聚合使用 curl_multi、連接池複用、限流熔斷
文件上傳使用 CURLFile 類、設置 CURLOPT_INFILESIZE
長連接複用設置 CURLOPT_FORBID_REUSE => false、CURLOPT_TCP_KEEPALIVE => true

常見坑點避雷

  1. POSTFIELDS 為數組時:自動設置 Content-Type 為 multipart/form-data,上傳文件需用 new CURLFile($path)
  2. HTTPS 請求失敗:生產環境務必配置 CURLOPT_CAINFO 指定 CA 證書包,勿長期關閉驗證
  3. 大文件下載:使用 CURLOPT_WRITEFUNCTION 流式寫入磁盤,避免內存溢出
  4. 編碼問題:統一使用 UTF-8,發送前 urlencode,接收後 urldecode

掌握 cURL 從基礎到多線程併發,是 PHP 開發者處理外部服務集成、微服務通信、數據採集的核心技能。建議在項目中封裝統一的 HTTP 客戶端類,統一異常處理、重試策略、監控指標,提升系統穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved