我想有从PHP发送的HTTP GET请求。 例:
http://tracker.example.com?product_number=5230&price=123.52
我们的想法是做服务器端的web分析:除了从JavaScript发送跟踪信息发送到服务器,服务器直接发送跟踪信息到另一个服务器。
要求:
为解决思路:
简而言之:什么是从PHP做一般的服务器端跟踪/分析的最佳解决方案。
不幸的是PHP顾名思义就是阻止 。 虽然这对于广大的功能,通常你会处理操作也是如此,目前的情况是不同的。
我喜欢叫的过程HTTP平 ,需要你只接触一个特定的URI,迫使特定的服务器开机它的内在逻辑。 有些功能让你实现非常相似,这个HTTP平的东西,通过不等待响应。
请注意该ping该URL的过程,是一个两步的过程:
- 解析DNS
- 发出请求
虽然提出请求应该是相当快,一旦DNS解析,并建立了连接,没有做DNS解析速度的方法很多。
做一个HTTP平的一些方法是:
- 卷曲 ,通过CONNECTION_TIMEOUT设定为较低的值
- 的fsockopen通过写入后立即关闭
- stream_socket_client (同的fsockopen)并且还加入
STREAM_CLIENT_ASYNC_CONNECT
尽管这两个cURL
和fsockopen
都阻挡而DNS被解决。 我注意到的fsockopen显著快,即使在最坏的情况。
stream_socket_client
,另一方面要解决这个问题有关DNS解析,并应在此方案中的最佳解决方案,但我没有设法得到它的工作。
最后一个解决办法是启动另一个线程/进程,这是否适合你。 制作一个系统调用这应该工作,而且还分叉当前进程应该这样做也。 不幸的是两者都没有在应用中,你无法控制在其PHP运行环境的真正安全。
系统调用往往比不堵塞,PCNTL默认情况下不启用。
我会打电话tracker.example.com是这样的:
get_headers('http://tracker.example.com?product_number=5230&price=123.52');
而在跟踪脚本:
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;
我实现了功能的快速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);
}
来到这里,同时研究类似的问题。 如果你有一个数据库连接方便,另外一个可能性是快速东东请求细节到一个表,然后有一个单独的基于时钟守护进程,定期扫描该表的新记录过程,并使得跟踪请求,释放不必使HTTP请求本身你的web应用。
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en"
)
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://tracker.example.com?product_number=5230&price=123.52', false, $context);
?>
我需要做同样的事情,只是ping一个网址,并丢弃所有响应。 我用proc_open命令,它可以让你结束进程马上使用proc_close。 我假设你有猞猁安装在服务器上:
<?php
function ping($url) {
$proc = proc_open("lynx $url",[],$pipes);
proc_close($proc);
}
?>
实际上,你可以做到这一点使用CURL
直接。
我都用很短的时间(实现了它CURLOPT_TIMEOUT_MS
)和/或使用curl_multi_exec
。
被告知:最终我放弃了这种方法,因为不是每个请求正确。 这可能是造成我自己的服务器,虽然我一直无法排除卷曲失败的选择。