不能输出不带换行符的大字符串块(nginx+php)

7

我尝试将一个大的JSON块(100k)打印到浏览器上,但服务器会无错误地失败。

例如:

echo 'var config =' . json_encode($config) . ';' . PHP_EOL;

我发现,如果我发送一个小段落,就没有问题。 我发现,如果我在JSON字符串中放入换行符,即使该字符串为400k,也没有问题。

例如:

$config_json = json_encode($config); $config_json = str_replace('},', '},' . PHP_EOL, $config_json); echo 'var config =' . $config_json . ';' . PHP_EOL;

但是换行符会破坏我的JSON格式。

那么,如果是缓冲设置的问题,为什么PHP_EOL能有所帮助呢?

我还尝试过像这里一样将JSON拆分成几个部分:https://dev59.com/wHbZa4cB1Zd3GeqPCSJ5#19156563,但没有成功,只有换行符能帮助我。


你尝试过禁用缓冲吗?http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffering?如果可以的话,你可以仅针对此响应进行操作:“通过在“X-Accel-Buffering”响应头字段中传递“yes”或“no”来启用或禁用缓冲。” - Robbie
如果您尝试打印JSON时遇到任何错误,例如“503服务器容量问题”或类似的内容,请检查。如果没有显示任何内容,则启用ini_set('error_reporting', 32767);并再次检查。 - Haridarshan
你看到了什么错误?nginx错误日志中有什么信息吗? - Rich
请查看此链接,或许可以帮助您 [https://dev59.com/8nE95IYBdhLWcg3wPrgI]。 - Marios Nikolaou
你尝试过循环遍历 $config 变量并构建像这样的 JSON 字符串吗? $str = '{'; $str .= '{ id:'. $value['id'].'}'; ... $str .= '}'; - MakeLoveNotWar
显示剩余3条评论
3个回答

1

当您编写代码时,如果服务器无错误而崩溃,我猜您的意思是服务器向客户端发送响应(状态码:200-无错误),但响应体(内容)为空(这就是失败原因)。

您应该检查一下,因为如果实际上服务器发送了一个有内容的响应,则问题不在于php、nginx或缓冲。

否则(如评论中建议的那样),也许JSON而不是在<script>-</script>块内被包装在<pre>标签之间,这可能是问题所在(但除非您发布更多的代码,否则我无法提供帮助)。


从现在开始,我假设从服务器发送的响应是

您发布的代码有效,并且应该正确处理您正在构建的输出字符串(远低于PHP限制)。

话虽如此,这似乎是一个奇怪的缓冲问题。我之所以说“奇怪”,是因为据我所知(我也花了一些时间进行研究),缓冲不应受换行符的影响。


我发现如果在JSON字符串中加入换行符,即使字符串达到400k也没有问题。
解决您的问题的一个快速方法是输出带有换行符的有效JSON。您只需要指定一个选项给json_encode函数:
echo 'var config = ' . json_encode( $config, JSON_PRETTY_PRINT ) . ';' . PHP_EOL;

JSON_PRETTY_PRINT告诉json_encode格式化json使之更易读,并且这样做会添加换行符。

(请注意,此选项仅适用于PHP 5.4.0及以上版本)


我希望以上解决方案适用于您。
无论如何,我强烈建议您进一步调查此问题,以使原始代码也能正常工作。
首先,您应确保正在运行最新和稳定版本的nginx和php。
然后,我会检查nginx配置文件、php-fpm配置(如果您正在使用php-fpm),最后是php配置。
还要检查php、nginx和php-fpm的错误日志。

JSON_PRETTY_PRINT 可用于 PHP 版本 > 5.4.0,请在您的答案中添加一个小注释。 - user2560539


0
如果您的服务器上没有安装PHP版本> 5.4.0,则可以快速解决问题,例如以下代码片段。下面的代码片段适用于测试数组。最初的测试是使用250Kb的数组。由于我无法在此处发布实际的测试数组,因此提供了一个test链接,其中包含较小的示例。但是,它是通过JSON_PRETTY_PRINT生成的结果。
$out = json_encode($arr,JSON_FORCE_OBJECT);
$out = str_replace( ':{', ':' . PHP_EOL . '    ' . '{', $out );
$out = str_replace( '},', PHP_EOL . '    },', $out );
$out = str_replace( ',', ',' . PHP_EOL  . '     ', $out );
$out = str_replace( '},' . PHP_EOL . '     ', '},' . PHP_EOL . ' ', $out );
$out = str_replace( '}}', PHP_EOL . '    }' . PHP_EOL . '}', $out );

echo $out;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接