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

PHP 模擬 POST 請求三大方法詳解:file_get_contents、cURL 與 Socket

     編輯:PHP 綜合知識

前言

雖然日常開發較少用到 PHP 模擬 POST 提交,但在 API 串接、第三方支付回調、爬蟲等場景中非常常見。本文整理三種主流實作方式並提供完整代碼範例。

方法一:file_get_contents + stream_context

利用 PHP 內建的串流上下文建立 HTTP POST 請求:

<?php
function file_get_contents_post($url, $post) {
    $options = array(
        'http' => array(
            'method'  => 'POST',
            'content' => http_build_query($post),
        ),
    );
    $result = file_get_contents($url, false, stream_context_create($options));
    return $result;
}

$data = file_get_contents_post(
    "https://www.a.com/post/post.php",
    array('name' => 'caiknife', 'email' => 'caiknife@gmail.com')
);
var_dump($data);

方法二:cURL 庫(推薦)

功能最完整、效能最好、支援 HTTPS、可設定超時、Header 等進階選項:

<?php
function curl_post($url, $post) {
    $options = array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => false,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $post,
    );
    $ch = curl_init($url);
    curl_setopt_array($ch, $options);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

$data = curl_post(
    "https://www.a.com/post/post.php",
    array('name' => 'caiknife', 'email' => 'caiknife@gmail.com')
);
var_dump($data);

方法三:Socket 底層實作

手動組裝 HTTP 協議封包,理解 HTTP 協議本質的最佳方式:

<?php
function socket_post($url, $post) {
    $urls = parse_url($url);
    if (!isset($urls['port'])) { $urls['port'] = 80; }

    $fp = fsockopen($urls['host'], $urls['port'], $errno, $errstr);
    if (!$fp) { echo "$errno, $errstr"; exit(); }

    $post = http_build_query($post);
    $length = strlen($post);

    $header = <<<HEADER
POST {$urls['path']} HTTP/1.1
Host: {$urls['host']}
Content-Type: application/x-www-form-urlencoded
Content-Length: {$length}
Connection: close

{$post}
HEADER;

    fwrite($fp, $header);
    $result = '';
    while (!feof($fp)) {
        $result .= fread($fp, 512);
    }
    // 移除 HTTP Header,只保留 Body
    $result = explode("\r\n\r\n", $result, 2);
    return $result[1];
}

$data = socket_post(
    "https://www.a.com/post/post.php",
    array('name' => 'caiknife', 'email' => 'caiknife@gmail.com')
);
var_dump($data);

關鍵差異比較

方法優點缺點適用場景
file_get_contents語法簡潔、無需擴充功能有限、難以處理複雜 Header簡單 GET/POST、內部服務呼叫
cURL功能完整、效能佳、支援多協議需安裝擴充(現代 PHP 預設啟用)生產環境首選、API 串接、爬蟲
Socket無依賴、可控制每個協議細節手動處理 Header/Body 分離、錯誤處理複雜教學用途、特殊協議需求

實戰封裝:通用 POST 請求函數

/**
 * 模擬 POST 進行 URL 請求
 * @param string $url
 * @param array  $post_data
 */
function request_post($url = '', $post_data = array()) {
    if (empty($url) || empty($post_data)) { return false; }

    // 陣列轉查詢字串
    $o = "";
    foreach ($post_data as $k => $v) {
        $o .= "$k=" . urlencode($v) . "&";
    }
    $post_data = substr($o, 0, -1);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

實際呼叫範例

function testAction() {
    $url = 'https://mobile.jschina.com.cn/jschina/register.php';
    $post_data = array(
        'appid'      => '10',
        'appkey'     => 'cmbohpffXVR03nIpkkQXaAA1Vf5nO4nQ',
        'member_name' => 'zsjs124',
        'password'   => '123456',
        'email'      => 'zsjs124@126.com',
    );
    $res = request_post($url, $post_data);
    print_r($res); // 通常回傳 JSON 格式
}

總結建議

  • 生產環境首選 cURL:穩定、功能完整、社群支援度高
  • 簡單需求可用 file_get_contents:無額外依賴、程式碼簡潔
  • Socket 適合學習 HTTP 協議:理解請求/回應結構、Header 處理
  • 注意:http_build_query() 會自動處理 URL 編碼,建議統一使用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved