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

PHP cURL 發送 JSON 資料完整範例(POST、Header 設定、錯誤處理)

     編輯:PHP 相關知識

呼叫 RESTful API 時常需以 JSON 格式 POST 資料。關鍵在於設定正確的 Content-Type: application/json 標頭,並將 PHP 陣列 json_encode 後送出。本文提供三種封裝層級的範例:直接呼叫、可重用函式、實際業務 JSON 結構(微信選單建立)。

核心關鍵點

$data = ['name' => 'Hagrid', 'age' => 36];
$json = json_encode($data);

$ch = curl_init('https://api.example.com/users');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS    => $json,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER    => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($json),
    ],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

必設 Header:Content-Type: application/json 告知伺服器請求體格式;Content-Length 雖非強制但建議加上,避免某些代理/伺服器拒絕 chunked 請求。

範例一:基礎 POST JSON

<?php
$data = ['name' => 'Hagrid', 'age' => '36'];
$json = json_encode($data);

$ch = curl_init('https://api.local/rest/users');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($json),
]);
$result = curl_exec($ch);
if ($result === false) {
    throw new Exception('cURL Error: ' . curl_error($ch));
}
curl_close($ch);
var_dump(json_decode($result, true));

範例二:封裝成可重用函式(支援錯誤碼、原始回應)

function httpPostJson(string $url, array $data, array $extraHeaders = []): array {
    $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST            => true,
        CURLOPT_POSTFIELDS      => $json,
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_HTTPHEADER      => array_merge([
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($json),
        ], $extraHeaders),
        CURLOPT_TIMEOUT         => 10,
        CURLOPT_CONNECTTIMEOUT  => 5,
        CURLOPT_SSL_VERIFYPEER  => true, // 生產環境保持 true
    ]);
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return [
        'http_code' => $httpCode,
        'body'      => $response,
        'error_no'  => $errno,
        'error_msg' => $error,
        'decoded'   => $errno === 0 ? json_decode($response, true) : null,
    ];
}

// 使用
$res = httpPostJson('https://api.example.com/orders', ['item_id' => 123, 'qty' => 2]);
if ($res['http_code'] === 200) {
    // 成功
}

範例三:複雜巢狀 JSON(微信自訂選單建立)

$menuJson = '{
    "button": [
        {"type":"click","name":"今日歌曲","key":"V1001_TODAY_MUSIC"},
        {"type":"click","name":"歌手簡介","key":"V1001_TODAY_SINGER"},
        {"name":"菜單","sub_button":[
            {"type":"click","name":"hello world","key":"V1001_HELLO_WORLD"},
            {"type":"click","name":"贊一下我們","key":"V1001_GOOD"}
        ]}
    ]
}';

$url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $accessToken;
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS    => $menuJson,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER    => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($menuJson),
    ],
]);
$response = curl_exec($ch);
// 成功回傳:{"errcode":0,"errmsg":"ok"}
curl_close($ch);

常見坑點檢查清單

現代替代:Guzzle / Symfony HttpClient

新專案建議使用 guzzlehttp/guzzle 或 symfony/http-client,提供 PSR-18 介面、中介軟體、非同步、自動重試等企業級功能,程式碼更簡潔:

$client = new \GuzzleHttp\Client();
$response = $client->post($url, ['json' => $data]); // 自動 json_encode + Header
$data = json_decode($response->getBody(), true);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因解決
伺服器回傳 400/415缺少或錯誤 Content-Type務必設定 application/json
中文變亂碼json_encode 預設轉義 Unicode加旗標 JSON_UNESCAPED_UNICODE
大數據截斷預設 POST 大小限制檢查 post_max_size、Nginx client_max_body_size
SSL 驗證失敗憑證不信任正確部署 CA 憑證,勿盲目關閉 CURLOPT_SSL_VERIFYPEER
超時無回應未設定 timeout務必設 CURLOPT_TIMEOUT、CURLOPT_CONNECTTIMEOUT