异步请求
在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); 实现