Php 为什么这段代码会对我的服务器';她的表现如何?

Php 为什么这段代码会对我的服务器';她的表现如何?,php,ajax,silverstripe,Php,Ajax,Silverstripe,我有一个Silverstripe站点,它处理非常大的数据。我制作了一个返回一个非常大转储的API,我在前端通过ajax get调用该API 当ajax调用API时,返回数据需要10分钟(非常长的json数据,客户接受) 当他们等待数据返回时,他们会在另一个选项卡中打开同一个站点来做其他事情,但是在上一个ajax请求完成之前,该站点的速度非常慢 在等待大的json数据时,我能做些什么来避免一切都没有响应 下面是代码及其功能的说明: 我创建了一个名为geteverything的方法,它驻留在web服

我有一个Silverstripe站点,它处理非常大的数据。我制作了一个返回一个非常大转储的API,我在前端通过ajax get调用该API

当ajax调用API时,返回数据需要10分钟(非常长的json数据,客户接受)

当他们等待数据返回时,他们会在另一个选项卡中打开同一个站点来做其他事情,但是在上一个ajax请求完成之前,该站点的速度非常慢

在等待大的json数据时,我能做些什么来避免一切都没有响应

下面是代码及其功能的说明:

我创建了一个名为
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,请参阅上面的代码,是的,它从另一个服务获取一个大流并返回它。人们当然可以直接链接到该流,除非该流无法从外部访问,或者该程序必须充当代理。