Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP echo json_逐行编码,而不是在最后处理内存问题,这是一个坏主意吗?_Php_Mysql_Json - Fatal编程技术网

PHP echo json_逐行编码,而不是在最后处理内存问题,这是一个坏主意吗?

PHP echo json_逐行编码,而不是在最后处理内存问题,这是一个坏主意吗?,php,mysql,json,Php,Mysql,Json,我需要以JSON格式输出至少500000行记录,最初使用如下内容 <?php $con=mysqli_connect("localhost",$username,$password,databaseName); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } $query =

我需要以JSON格式输出至少500000行记录,最初使用如下内容

<?php

  $con=mysqli_connect("localhost",$username,$password,databaseName);

  // Check connection
  if (mysqli_connect_errno())
  {
   echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

  $query = "the query here";

  $result = mysqli_query($con,$query);

  $rows = array();
  while($r = mysqli_fetch_array($result)) {
    $rows[] = $r;
  }
  echo json_encode($rows);

  mysqli_close($con);
?>
我没有在最后输出行,而是在每次MySQL迭代中输出每一行。因此,无需将所有行存储在变量缓冲区中

我拥有的500000行记录运行良好。然而,当我在网上搜索时,没有人做我做的事情。所以我的问题是:

  • 我的逐行
    echo json_encode()
    方法使用安全吗
  • 如果没有,是否有更好的方法来解决内存不足问题?(资源有限,不能增加内存)

  • 由于内存中没有保存整个JSON文档的内存,请考虑一个更具内存效率的替代方案:

    将每一行转储为一个简单数组,从而避免对每一行重复键。例如,而不是:

    [
      { "id": 1, "valueA": "A", ... },
      { "id": 2, "valueA": "A", ... },
      ...
    ]
    
    考虑做:

    {
      "columns": [ "id", "valueA", ... ],
      "values": [
        [ 1, "A" ],
        [ 2, "A" ],
        ...
      ]
    }
    
    在实践中,这会导致文件大大缩小

    您可能还需要考虑,或行分隔的JSON,其中每行输出一个文档:

    虽然这并没有减少结果的总体大小,但它确实使另一端的解析更加容易。阅读器只需要足够的内存来容纳最大的单行文档,而不是一次容纳所有500K文档

    如果您的web服务器支持流式处理结果,那么它也可能具有性能优势,因为您可以在加载所有记录之前开始传输记录


    考虑一下:如果您没有足够的内存来生成整个文档,那么如果手头没有太多的内存,如何使用它呢?行分隔的JSON更易于阅读,您可以将其流式输入,快速迭代。

    我昨天遇到了这个问题。我的解决方案是创建一个CSV文件而不是JSON。您的解决方案将适用于创建JSON的脚本,但读取该脚本的脚本在尝试解码时可能会耗尽内存。感谢您在@Barmar上的评论,但在我的示例中需要同时支持CSV和JSON。这是一个供外人使用的API,因此理论上他们可以获取我们的所有数据,他们如何处理数据我无法理解,但需要提供这样做的选项。许多公共API限制您一次可以请求的记录数,并要求调用方执行多个调用以获取所有信息。这可能就是原因。例如,当我们使用Stripe API下载本月的事务时,我们必须以100块为单位进行下载。哦,你是对的,所以我的需求中存在一个设计缺陷。我应该将系统设计为不同时输出所有json。因为使用我们的API的人无论如何也无法获取所有记录。我已经阅读了您提供的页面,这似乎是缩短我的API的一个好方法。我还将使用@barmar comment,它允许API以一定的长度进行收集,这将更加实用。谢谢大家!分页和流媒体的组合将对解决您的问题有很大帮助。希望你能修好它!
    {
      "columns": [ "id", "valueA", ... ],
      "values": [
        [ 1, "A" ],
        [ 2, "A" ],
        ...
      ]
    }
    
    { "id": 1, "valueA": "A", ... }
    { "id": 2, "valueA": "A", ... }