异步请求

PHP中实现异步请求有下面几种方法.

适合通知类、日志上报等无需等待响应的场景。

cURL

$ch = curl_init('https://api.example.com/notify');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['msg' => 'hello']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100); // 100毫秒超时
curl_exec($ch);
curl_close($ch);

fsockopen

$host = 'api.example.com';
$port = 80;
$path = '/notify';
$data = http_build_query(['msg' => 'hello']);
$fp = fsockopen($host, $port, $errno, $errstr, 1);
if ($fp) {
    // http 协议格式
    $out = "POST $path HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out .= "Content-Length: " . strlen($data) . "\r\n";
    $out .= "Connection: Close\r\n\r\n";
    $out .= $data;
    fwrite($fp, $out);
    fclose($fp); // 立即关闭,不等待响应
}

stream_socket_client

$host = 'api.example.com';
$port = 80;
$path = '/notify';
$data = http_build_query(['msg' => 'hello']);
$fp = stream_socket_client("tcp://$host:$port", $errno, $errstr, 1);
if ($fp) {
    $out = "POST $path HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out .= "Content-Length: " . strlen($data) . "\r\n";
    $out .= "Connection: Close\r\n\r\n";
    $out .= $data;
    fwrite($fp, $out);
    fclose($fp); // 立即关闭,不等待响应
}

GuzzleHttp (推荐现代项目)

// 需先 composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client();
$promise = $client->postAsync('https://api.example.com/notify', [
    'form_params' => ['msg' => 'hello']
]);
// 不调用 wait()

proc_open/shell_exec

// 使用 proc_open 异步发起 HTTP 请求(后台执行 curl)
$cmd = "curl -X POST -d 'msg=hello' https://api.example.com/notify > /dev/null 2>&1 &";
$descriptorspec = [
    0 => ["pipe", "r"],
    1 => ["pipe", "w"],
    2 => ["pipe", "w"]
];
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
    proc_close($process); // 立即关闭,不等待
}
// 说明:也可用 shell_exec($cmd); 实现