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

PHP cURL 發送 POST 請求完整指南:四種數據格式、Header 設置、錯誤處理

     編輯:PHP 綜合知識

cURL POST 核心流程

function httpPost(string $url, $data, array $options = []): string {
    $ch = curl_init($url);
    $defaultOpts = [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $data,           // 關鍵:數據格式決定 Content-Type
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,       // 生產環境請設 true 並配置 CA 證書
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_HTTPHEADER => ['Expect:'],     // 避免 100 Continue 導致延遲
    ];
    curl_setopt_array($ch, array_merge($defaultOpts, $options));
    $response = curl_exec($ch);
    if ($response === false) throw new Exception('cURL 錯誤: ' . curl_error($ch), curl_errno($ch));
    curl_close($ch);
    return $response;
}

四種 POST 數據格式深度解析

格式PHP 數據結構自動 Content-Type適用場景接收端獲取方式
application/x-www-form-urlencoded字符串 "a=1&b=2" 或 一維數組 ['a'=>1,'b'=>2]✅ 自動設置簡單鍵值對、表單提交、大多數 APIPHP: $_POST / $_REQUEST
multipart/form-data多維數組或包含 CURLFile 對象✅ 自動設置 (含 boundary)文件上傳、混合表單字段PHP: $_POST + $_FILES
application/jsonJSON 字符串 json_encode($arr)❌ 需手動設置 HeaderREST API、複雜嵌套數據、微信/支付寶回調PHP: file_get_contents('php://input') + json_decode
application/xml / text/xmlXML 字符串❌ 需手動設置 Header銀行/物流/ERP 老舊接口、SOAPPHP: simplexml_load_string(file_get_contents('php://input'))

實戰代碼示例

1. 表單數組 (urlencoded)

$data = ['name' => '張三', 'age' => 25, 'tags' => ['php', 'go']];
// 注意:一維數組中值若為數組,會被 PHP 序列化為 tags[0]=php&tags[1]=go
$res = httpPost('https://api.example.com/user', $data);

2. 文件上傳 (multipart)

$data = [
    'username' => 'admin',
    'avatar' => new CURLFile('/path/to/avatar.jpg', 'image/jpeg', 'avatar.jpg'), // PHP 5.5+
    'documents' => [
        new CURLFile('/path/to/doc1.pdf'),
        new CURLFile('/path/to/doc2.pdf'),
    ]
];
$res = httpPost('https://api.example.com/upload', $data);

3. JSON API (最常見)

$payload = [
    'order_id' => '20240101001',
    'items' => [
        ['sku' => 'SKU001', 'qty' => 2, 'price' => 99.00],
        ['sku' => 'SKU002', 'qty' => 1, 'price' => 149.00]
    ],
    'buyer' => ['id' => 12345, 'name' => '李四']
];
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$res = httpPost('https://api.example.com/order', $json, [
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($json),
        'Authorization: Bearer ' . $accessToken
    ]
]);
// 接收端
$input = file_get_contents('php://input');
$data = json_decode($input, true);

4. 原始 XML (SOAP/老接口)

$xml = '<?xml version="1.0"?><request><cmd>query</cmd><params><id>123</id></params></request>';
$res = httpPost('https://legacy.example.com/gateway', $xml, [
    CURLOPT_HTTPHEADER => ['Content-Type: text/xml; charset=utf-8', 'SOAPAction: "query"']
]);

常見坑位與解決方案

  1. JSON 數據 $_POST 為空:$_POST 只解析 urlencoded/multipart。JSON 需用 php://input。
    ✅ 解決:接收端統一用 $input = file_get_contents('php://input'); $data = json_decode($input, true);
  2. 數組深度過深導致丟失:urlencoded 只支援一維,多維需 http_build_query($arr) 扁平化。
    ✅ 解決:$data = http_build_query($deepArray); // 自動生成 a[b][c]=1 格式
  3. 文件上傳 @ 符號棄用:PHP 5.6+ 棄用 '@/path/file' 語法,必須用 CURLFile。
    ✅ 解決:new CURLFile($path, $mime, $name)
  4. SSL 證書驗證失敗:生產環境 CURLOPT_SSL_VERIFYPEER => true,需部署 CA 證書包。
    ✅ 解決:CURLOPT_CAINFO => '/etc/ssl/certs/ca-certificates.crt'
  5. 超時設置:CURLOPT_TIMEOUT (總超時) + CURLOPT_CONNECTTIMEOUT (連接超時),防止掛死進程。

封裝建議:統一 HTTP 客戶端類

class HttpClient {
    private $defaultHeaders = ['User-Agent' => 'MyApp/1.0'];
    
    public function postJson(string $url, array $data, array $headers = []): array {
        $json = json_encode($data, JSON_UNESCAPED_UNICODE);
        $raw = $this->request('POST', $url, $json, array_merge($headers, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($json)
        ]));
        return json_decode($raw, true) ?: [];
    }
    
    public function postForm(string $url, array $data, array $headers = []): array {
        return $this->request('POST', $url, $data, $headers);
    }
    
    private function request(string $method, string $url, $body, array $headers): string {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_POSTFIELDS => $body,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => array_merge($this->defaultHeaders, $headers),
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_CAINFO => __DIR__ . '/cacert.pem',
            CURLOPT_TIMEOUT => 15,
        ]);
        $resp = curl_exec($ch);
        if ($resp === false) throw new HttpException(curl_error($ch), curl_errno($ch));
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($code >= 400) throw new HttpException("HTTP $code: $resp", $code);
        return $resp;
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved