如何无需等待响应且不使用AJAX发送请求?cURL优化方案问询
无需等待响应且不使用AJAX的请求发送方案
嘿,这个问题我之前也碰到过!想要发送请求但完全不想等响应,确实不用AJAX也有不少靠谱的办法,给你整理几个实用的方案:
方案1:用fsockopen直接发送请求后立即关闭连接
这是最直接的方式,通过底层套接字发送HTTP请求头,发完就断开连接,完全不用等待服务器响应,耗时极短。
$host = 'example.com'; $path = '/?action=example'; $port = 80; // 建立套接字连接,设置极短超时(0.5秒足够) $socket = fsockopen($host, $port, $errno, $errstr, 0.5); if ($socket) { // 构造标准的HTTP GET请求头 $request = "GET {$path} HTTP/1.1\r\n"; $request .= "Host: {$host}\r\n"; $request .= "Connection: Close\r\n\r\n"; // 发送请求后立刻关闭连接,不等回复 fwrite($socket, $request); fclose($socket); }
解释:服务器收到请求后会正常处理,但我们这边发完就断开,不会阻塞当前进程,几乎是瞬间完成。
方案2:优化cURL参数实现极致短超时
你之前用的CURLOPT_TIMEOUT设1秒还是太长,我们可以用毫秒级超时加上几个关键参数,让cURL放弃等待响应的时间缩到最短:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://example.com?action=example'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100); // 仅等待100毫秒响应 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 50); // 连接超时50毫秒 curl_setopt($ch, CURLOPT_NOSIGNAL, true); // Linux下避免信号干扰导致超时不准确 curl_setopt($ch, CURLOPT_FORBID_REUSE, true); // 不复用连接,减少后续处理 curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); // 强制新建连接 curl_exec($ch); curl_close($ch);
解释:这样设置后,cURL会在几十毫秒内结束请求,比1秒的方式高效太多,而且代码改动很小,容易上手。
方案3:用pcntl_fork创建子进程处理请求
如果你的请求需要一定时间才能发送完成,但又不想阻塞主进程的逻辑,可以用fork子进程的方式,主进程直接继续运行,子进程在后台发送请求:
$pid = pcntl_fork(); if ($pid == -1) { // 创建子进程失败,这里可以加错误处理逻辑 error_log("Failed to fork process"); } elseif ($pid == 0) { // 子进程:负责发送请求 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://example.com?action=example'); curl_exec($ch); curl_close($ch); exit(); // 子进程执行完必须退出,避免干扰主进程 } else { // 主进程:直接继续自己的业务逻辑,不用等子进程 // 用WNOHANG参数非阻塞等待,避免产生僵尸进程 pcntl_wait($status, WNOHANG); }
解释:这个方式适合需要保证请求能完整发送,但又不想让主进程等待的场景,不过要注意服务器需要支持pcntl扩展(一般Linux环境默认支持)。
方案4:PHP-FPM环境下用fastcgi_finish_request后台处理
如果是Web请求场景,你可以先给客户端返回响应,然后在服务器后台悄悄发送请求,用户完全感觉不到延迟:
// 先给前端返回响应,告诉用户操作完成 echo "请求已提交成功"; // 结束和客户端的连接,但当前进程继续运行 fastcgi_finish_request(); // 现在在后台发送请求,不用管响应结果 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://example.com?action=example'); curl_exec($ch); curl_close($ch);
解释:这个方法非常适合Web应用中“提交操作后不用等处理结果”的场景,用户拿到响应后,服务器在后台完成请求发送。
内容的提问来源于stack exchange,提问作者user3438958




