当我运行命令计划laravel时,如何解决“致命错误:内存不足...”?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当我运行命令计划laravel时,如何解决“致命错误:内存不足...”?相关的知识,希望对你有一定的参考价值。

我的命令是这样的:

<?php
namespace AppConsoleCommands;
use IlluminateConsoleCommand;
use AppModelsItemDetail;
class ImportItemDetail extends Command
{
    protected $signature = 'sync:item-detail';
    protected $description = 'sync item detail';
    public function __construct()
    {
        parent::__construct();
        ini_set('max_execution_time', 0);
        ini_set('memory_limit', '-1');
    }
    public function handle()
    {
        $path = storage_path('json/ItemDetail.json');
        $json = json_decode(file_get_contents($path), true);
        foreach ($json['value'] as $value) {
            ItemDetail::updateOrCreate(
                [ 'entry_number' => $value['Entry_Number'] ],
                [ 
                    'item_number' => $value['Item_Number'],
                    'description' => $value['Description'],
                    ....
                ]
            );
        }
    }
}

如果我运行该命令,则存在如下错误:

Fatal error: Out of memory (allocated 255852544) (tried to allocate 8192 bytes)

虽然我在构造中设置了ini_set('memory_limit', '-1');

我该如何解决错误?

注意 :

我在json文件中的记录包含数十万个数据。因此,检查该字段需要很长时间

更新

我的ItemDetail.json是这样的:

{
  "@odata.context":"http://myapp-svr01.www.myapp.com:1224/DynamicsNAV100/ODataV4/$metadata#Collection(NAV.ODATAITEM)","value":[
    {
      "@odata.etag":"W/"JzE2O0lBQUFBQUNIbXdrQ0FBQAD5OzE4ODQ1MDQ4NjA7Jw=="","Entry_Number":123,"Item_Number":"9805010101","Variant_Code":"039","Posting_Date":"2018-01-02T00:00:00Z","Entry_Type":"Sale","Description":"MISC BISBAN POLOS 11MM A847","Quantity":-7200,"Source_Type":"Customer","Order_Type":" ","Sales_Amount_Actual":1800000,"ETag":"16;IAAAAACHmwkCAAAA9;1884504860;"
    },{
      "@odata.etag":"W/"JzE2O0lBQUFBQUNIbkFrQ0FBQAD5OzE4ODQ1MDQ5MTA7Jw=="","Entry_Number":124,"Item_Number":"9805010102","Variant_Code":"100","Posting_Date":"2018-01-02T00:00:00Z","Entry_Type":"Sale","Description":"MISC BISBAN POLOS 11MM A915","Quantity":-7200,"Source_Type":"Customer","Order_Type":" ","Sales_Amount_Actual":1800000,"ETag":"16;IAAAAACHnAkCAAAA9;1884504910;"
    }
  ]
}

我只在json上面给了2条记录。实际上有大约150,000条记录

答案

问题是你是在一次读取整个文件,而是应该以块或逐行读取它。例如:

$items = [];
$file = fopen(storage_path('json/ItemDetail.json'),'r');
while (!feof($file)){
    $line = fgets($file);
    $obj = json_decode($line);
    // $obj is type stdClass
    // transform $obj to fit the update or create method
    ItemDetail::updateOrCreate( ... )
}

更新

在处理大文件时,您应该查看流式解析器。

jsonstreamingparser将是一个不错的选择。

以上是关于当我运行命令计划laravel时,如何解决“致命错误:内存不足...”?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 5.2 版本在本地运行 laravel 项目

无法从工匠命令 Laravel/Lumen 进行 Crypt::decrypt

如何解决 laravel 迁移错误“一般错误:1005 无法创建表”

如何在线运行 Laravel 调度命令作为 Cron Job

当我运行任何关于 npm 的命令时如何解决问题它显示错误

根据环境变量运行 Laravel 命令