Php 为什么这段代码会对我的服务器';她的表现如何?
我有一个Silverstripe站点,它处理非常大的数据。我制作了一个返回一个非常大转储的API,我在前端通过ajax get调用该API 当ajax调用API时,返回数据需要10分钟(非常长的json数据,客户接受) 当他们等待数据返回时,他们会在另一个选项卡中打开同一个站点来做其他事情,但是在上一个ajax请求完成之前,该站点的速度非常慢 在等待大的json数据时,我能做些什么来避免一切都没有响应 下面是代码及其功能的说明: 我创建了一个名为Php 为什么这段代码会对我的服务器';她的表现如何?,php,ajax,silverstripe,Php,Ajax,Silverstripe,我有一个Silverstripe站点,它处理非常大的数据。我制作了一个返回一个非常大转储的API,我在前端通过ajax get调用该API 当ajax调用API时,返回数据需要10分钟(非常长的json数据,客户接受) 当他们等待数据返回时,他们会在另一个选项卡中打开同一个站点来做其他事情,但是在上一个ajax请求完成之前,该站点的速度非常慢 在等待大的json数据时,我能做些什么来避免一切都没有响应 下面是代码及其功能的说明: 我创建了一个名为geteverything的方法,它驻留在web服
geteverything
的方法,它驻留在web服务器上,如下所示,它访问另一个服务器(数据服务器),通过流式API(位于数据服务器中)获取数据。数据量大,数据服务器速度慢;我的客户不介意这个请求花费很长时间,他们介意其他事情变得有多慢。会话用于确定请求的细节
protected function geteverything($http, $id) {
if(($System = DataObject::get_by_id('ESM_System', $id))) {
if(isset($_GET['AAA']) && isset($_GET['BBB']) && isset($_GET['CCC']) && isset($_GET['DDD'])) {
/**
--some condition check and data format for AAA BBB CCC and DDD goes here
**/
$request = "http://dataserver/streaming?method=xxx";
set_time_limit(120);
$jsonstring = file_get_contents($request);
echo($jsonstring);
}
}
}
我该如何解决这个问题,或者您还需要知道什么才能提供帮助?花费这么长时间的原因是您将json的完整性下载到服务器,然后将其全部发送给用户。在开始发送之前,无需等待您获取整个文件 不要使用
file\u get\u contents
与curl建立连接,并将输出直接写入php://output
例如,此脚本将按原样复制:
<?php
// Initialise cURL. You can specify the URL in curl_setopt instead if you prefer
$ch = curl_init("http://example.com/");
// Open a file handler to PHP's output stream
$fp = fopen('php://output', 'w');
// Turn off headers, we don't care about them
curl_setopt($ch, CURLOPT_HEADER, 0);
// Tell curl to write the response to the stream
curl_setopt($ch, CURLOPT_FILE, $fp);
// Make the request
curl_exec($ch);
// close resources
curl_close($ch);
fclose($fp);
文件获取内容()完成后,$jsonstring
有多大?值得一读的是,它以更小的(比如512个字符)块,边写边读,这样就永远不会将整个转储存储在内存中。还有,数据的字符集是什么?你必须处理多字节字符吗?谢谢你修复我的英语(提姆:)对,但它有多大?例如,strlen($jsonstring)
-我很好奇$jsonstring
一旦文件获取内容()
完成,会占用多少内存。可能值得使用fsockopen()
,一次只读取1k,并在运行时以循环方式将其写入浏览器。目前,您将所有数据存储在内存中,然后将其写入浏览器,这可能是您的速度减慢的原因。数据多久更改一次,您能否每天提取并缓存数据?或者,在上午8点和下午5点之间,有一个每15分钟获取一次的进程,并使其自身保持最新?也许限制你返回的数量,获取最新的50行,如果他们想要更多,再获取50行等等@Wizzard,请参阅上面的代码,是的,它从另一个服务获取一个大流并返回它。人们当然可以直接链接到该流,除非该流无法从外部访问,或者该程序必须充当代理。