如何在不发生内存崩溃的情况下将大块存储到 json 文件中?

How can I store large chunks into json file without memory crash?

我有一个数组 $table,它包含 6000 个项目。 当我想将此数组转换为 json 并将其存储到文件中时,我的内存崩溃了。 所以我有了将数组分成包含 500 个项目的块的想法:

$table = array_chunk($table, 500);

$table_json = $serializer->serialize($table[0], 'json', $context);

$myfile = fopen($_SERVER['DOCUMENT_ROOT']."/files/myfile.json", "w") or die("Unable to open file!");
file_put_contents($_SERVER['DOCUMENT_ROOT']."/files/myfile.json", $table_json);

现在运行速度很快,但当然现在只存储了 500 个项目。有没有办法添加 $table 数组的其他部分而不会导致内存崩溃?

坚持您的解决方案,您可以将其他块附加到现有文件。这适用于 setting the flag FILE_APPEND,例如:

$table_json = $serializer->serialize($table[1], 'json', $context);
$myfile = fopen($_SERVER['DOCUMENT_ROOT']."/files/myfile.json", "w") or die("Unable to 
open file!");
file_put_contents($_SERVER['DOCUMENT_ROOT']."/files/myfile.json", $table_json, FILE_APPEND | LOCK_EX);

(LOCK_EX 防止其他人同时写入文件的标志)

你可以像你提到的那样做这样的事情,你知道如何使用 array_chunk(); 让我们研究一下使用名为 array_chunk();

的内置 PHP 函数来简化该过程

我们将使用 HTML table 进行设计,但不推荐这样做。使用 CSS 可以更好地完成任务,您可以在没有 HTML 和 CSS.

的情况下按照相同的方式进行操作

我们的 table :

id  datePosted  firstName   lastName    pictureName          anotherColumn
1   2013-07-01  John        Smith       SmithJohn.jpg        anotherValue
2   2013-05-06  Elroy       Johnson     JohnsonElroy.jpg     anotherValue
3   2013-06-18  Jake        Bible       BibleJake.jpg        anotherValue
4   2013-07-17  Steve       Stevenson   StevensonSteve.jpg   anotherValue
5   2013-04-08  Bill        Smith       SmithBill2.jpg       anotherValue

构建 HTML 表

PDO 查询用于通过准备语句抓取数据库信息,注意循环只生成显示列的代码。 检测行开始和结束位置的测试是不必要的。

//INITIALIZE VARIABLES
$colsToDisplay = 3;
$htmlOutput    = array();

//GET PICTURE LIST
$sql = "SELECT datePosted, firstName, lastName, pictureName FROM pictureList ORDER BY datePosted DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
     $htmlOutput[] = "<td><img src='images/{$row['pictureName']}' alt='' /><br />{$row['firstName']} {$row['lastName']}</td>";
}

循环完成后,包含列信息的数组可以分成三组...或分配给 $colsToDisplay 的任何值,我们在这里做了什么? 我们从 table 中取出了 3 列,所以将 table 分成两部分。

while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
     //...
}

//BREAK THE COLUMNS INTO GROUPS
$htmlOutput = array_chunk($htmlOutput, $colsToDisplay);

剩下的就是显示table信息了。请注意,array_chunk() creates a multi-dimensional array. The foreach loop is used to process the groups of columns. Each group is assigned to $currRow which contains an array of columns for the current row. The implode() 函数用于快速将列显示为字符串。

让我们继续:

//BREAK THE COLUMNS INTO GROUPS
$htmlOutput = array_chunk($htmlOutput, $colsToDisplay);

//DISPLAY TABLE
print '<table>';
foreach($htmlOutput as $currRow) {
     print '<tr>' . implode('', $currRow) . '</tr>';
}
print '</table>';

检查缺少的列标签

您可能已经注意到,添加缺失列的代码被遗漏了。 换句话说,此示例导致 HTML table,其中最后一行只有两列。

显然,根据 W3C Markup Validation Service… 不需要缺少的列,因此未包括在内。但是,可以在调用 array_chunk() 之前通过 运行 以下代码添加它们。

$colsDifference = count($htmlOutput) % $colsToDisplay;
if($colsDifference) {
     while($colsDifference < $colsToDisplay) {           
        $htmlOutput[] = '<td></td>';           
        $colsDifference++;
    } 
} 

最终代码:

    //INITIALIZE VARIABLES
    $colsToDisplay = 3;
    $htmlOutput    = array();


    //GET PICTURE LIST
    $sql = "SELECT datePosted, firstName, lastName, pictureName FROM pictureList ORDER BY datePosted DESC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
         $htmlOutput[] = "<td><img src='images/{$row['pictureName']}' alt='' /><br />{$row['firstName']} {$row['lastName']}</td>";
    }

    //OPTIONAL CODE
    //IF NEEDED, ADD MISSING COLUMNS
    $colsDifference = count($htmlOutput) % $colsToDisplay;
    if($colsDifference) {
         while($colsDifference < $colsToDisplay) {           
            $htmlOutput[] = '<td></td>';           
            $colsDifference++;      
        }
    } 
        //END: OPTIONAL CODE  
        //BREAK THE COLUMNS INTO GROUPS 
   $htmlOutput = array_chunk($htmlOutput, $colsToDisplay);   
        //DISPLAY TABLE print '<table>'; 

    foreach($htmlOutput as $currRow) {      
        print '<tr>' . implode('', $currRow) . '</tr>'; 
    } 
    print '</table>'; 

本教程背后的想法:

  1. 您无需创建文件并将数组写入该文件即可在数据中显示table。
  2. 如果你仍然想要,你可以(将 table 分成两部分)创建两个数组然后写入文件,然后使用 array_push();array_merge(); 来获取两个数组数组合二为一。

我可能解释得不好,请原谅错误,希望这对您的编码生活有所帮助:)