fek*_*lee 40 php curl http server-side web-analytics
我希望从PHP发送HTTP GET请求.例:
http://tracker.example.com?product_number=5230&price=123.52
Run Code Online (Sandbox Code Playgroud)
我们的想法是进行服务器端网络分析:服务器不是将跟踪信息从JavaScript发送到服务器,而是将跟踪信息直接发送到另一台服务器.
要求:
请求应该花费尽可能少的时间,以便不会明显延迟PHP页面的处理.
tracker.example.com不需要检查来自的响应.作为示例,一些可能的响应来自
tracker.example.com:
200:没关系,但不需要检查.
404:运气不好,但是 - 再次 - 不需要检查.
301:虽然重定向是合适的,但它会延迟PHP页面的处理,所以不要这样做.
简而言之:可以丢弃所有回复.
解决方案的想法:
在一个现在删除的答案中,有人建议在shell进程中从PHP 调用命令行 curl.这似乎是一个好主意,只是我不知道在重负载下分配大量shell进程是否明智.
我找到了php-ga,一个用于从PHP进行服务器端Google Analytics的软件包.在项目的页面上,提到:"可以配置为使用非阻塞请求." 到目前为止,我还没有时间研究php-ga内部使用的方法,但这种方法可能就是这样!
简而言之:从PHP进行通用服务器端跟踪/分析的最佳解决方案是什么.
Khe*_*hez 29
不幸的是,PHP的定义是阻塞.虽然这适用于您通常要处理的大多数功能和操作,但当前情况不同.
我喜欢称之为HTTP-Ping的过程要求您只触摸特定的URI,强制特定的服务器启动它的内部逻辑.某些函数允许您通过不等待响应来实现与此HTTP-ping非常相似的操作.
请注意,ping网址的过程分为两个步骤:
虽然在解析DNS并建立连接后,请求应该相当快,但没有多少方法可以更快地解析DNS.
执行http-ping的一些方法是:
STREAM_CLIENT_ASYNC_CONNECT虽然两者cURL并fsockopen都阻挡而DNS被解决.我注意到即使在最坏的情况下,fsockopen也要快得多.
stream_socket_client 另一方面,应该解决有关DNS解析的问题,并且应该是这种情况下的最佳解决方案,但我还没有设法让它工作.
最后一个解决方案是启动另一个为您执行此操作的线程/进程.对此进行系统调用应该有效,但也要分支当前进程也应该这样做.不幸的是,在无法控制运行PHP的环境的应用程序中,两者都不是很安全.
系统调用通常被阻止,默认情况下不启用pcntl.
Raf*_*shi 14
我会这样调用tracker.example.com:
get_headers('http://tracker.example.com?product_number=5230&price=123.52');
Run Code Online (Sandbox Code Playgroud)
并在跟踪器脚本中:
ob_end_clean();
ignore_user_abort(true);
ob_start();
header("Connection: close");
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// from here the response has been sent. you can now wait as long as you want and do some tracking stuff
sleep(5); //wait 5 seconds
do_some_stuff();
exit;
Run Code Online (Sandbox Code Playgroud)
CET*_*ETb 11
我实现了对url的快速GET请求的功能而无需等待响应:
function fast_request($url)
{
$parts=parse_url($url);
$fp = fsockopen($parts['host'],isset($parts['port'])?$parts['port']:80,$errno, $errstr, 30);
$out = "GET ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Length: 0"."\r\n";
$out.= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fclose($fp);
}
Run Code Online (Sandbox Code Playgroud)
我们正在使用fsockopen和fwrite组合,然后有一天它停止工作了。或者说是间歇性的。经过一些研究和测试,如果您启用了 fopen 包装器,我最终会使用file_get_contents和stream_context_create函数,并将超时设置为 100 秒。超时参数可以接收浮动值(https://www.php.net/manual/en/context.http.php)。我将它包装在 try...catch 块中,这样它就会默默地失败。它非常适合我们的目的。如果需要,您可以在 catch 中进行记录。如果您不希望函数阻塞运行时,超时是关键。
function fetchWithoutResponseURL( $url )
{
$context = stream_context_create([
"http" => [
"method"=>"GET",
"timeout" => .01
]
]
);
try {
file_get_contents($url, 0, $context);
}catch( Exception $e ){
// Fail silently
}
}
Run Code Online (Sandbox Code Playgroud)