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

PHP 程序內部發起 POST 請求:cURL 封裝最佳實踐

     編輯:PHP 綜合知識

核心封裝函數

<?php
function http_post(string $url, array $data, array $options = []): string|false {
    $defaults = [
        'timeout' => 10,
        'connect_timeout' => 5,
        'headers' => ['Content-Type: application/x-www-form-urlencoded'],
        'follow_location' => true,
        'max_redirects' => 3,
        'ssl_verify_peer' => true,
        'ssl_verify_host' => 2,
    ];
    $opts = array_merge($defaults, $options);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data), // 自動編碼
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $opts['timeout'],
        CURLOPT_CONNECTTIMEOUT => $opts['connect_timeout'],
        CURLOPT_FOLLOWLOCATION => $opts['follow_location'],
        CURLOPT_MAXREDIRS => $opts['max_redirects'],
        CURLOPT_SSL_VERIFYPEER => $opts['ssl_verify_peer'],
        CURLOPT_SSL_VERIFYHOST => $opts['ssl_verify_host'],
        CURLOPT_HTTPHEADER => $opts['headers'],
    ]);

    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    if ($errno) {
        error_log("cURL error [$errno] $error for $url");
        return false;
    }

    if ($info['http_code'] >= 400) {
        error_log("HTTP {$info['http_code']} for $url");
    }

    return $response;
}

// 使用
$res = http_post('https://api.example.com/notify', [
    'event' => 'order_created',
    'order_id' => 12345,
    'amount' => 99.00,
]);
if ($res !== false) {
    $result = json_decode($res, true);
    // 處理結果
}
?>

關鍵點解析

項目說明
http_build_query自動處理數組編碼、巢狀結構、URL 編碼,比手動拼接安全
CURLOPT_RETURNTRANSFER返回響應體而非直接輸出
超時設置區分連接超時與總超時,防止掛死
SSL 驗證生產環境必須開啟,內網可關閉
錯誤處理檢查 curl_errno、http_code,記錄日志
JSON POST設置 Content-Type: application/json,CURLOPT_POSTFIELDS => json_encode($data)

進階:併發請求

function http_post_multi(array $requests, array $options = []): array {
    $mh = curl_multi_init();
    $handles = [];

    foreach ($requests as $i => [$url, $data]) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($data),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $options['timeout'] ?? 10,
        ]);
        curl_multi_add_handle($mh, $ch);
        $handles[$i] = $ch;
    }

    $running = null;
    do {
        curl_multi_exec($mh, $running);
        curl_multi_select($mh, 0.1);
    } while ($running);

    $results = [];
    foreach ($handles as $i => $ch) {
        $results[$i] = [
            'response' => curl_multi_getcontent($ch),
            'info' => curl_getinfo($ch),
            'error' => curl_error($ch),
        ];
        curl_multi_remove_handle($mh, $ch);
    }
    curl_multi_close($mh);
    return $results;
}

現代替代:Guzzle / Http\Client

composer require guzzlehttp/guzzle

use GuzzleHttp\Client;
$client = new Client(['timeout' => 10]);
$response = $client->post('https://api.example.com/notify', [
    'form_params' => ['event' => 'order_created', 'order_id' => 12345],
    'headers' => ['X-Custom' => 'value'],
]);
$data = json_decode($response->getBody(), true);

新項目強烈建議直接用 Guzzle:PSR-18 兼容、中間件、重試、異步、測試雙工、完整類型提示。原生 cURL 僅用於無 Composer 環境或極簡腳本。

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