为了账号安全,请及时绑定邮箱和手机立即绑定

Storage::append() 中“Allowed memory size

Storage::append() 中“Allowed memory size

PHP
千巷猫影 2023-03-26 14:50:48
我用 Laravel 实现了一个代码来处理块上传,如下所示。// if total size equals length of file we have gathered all patch filesif ($size == $length) {    // write patches to file    foreach ($patch as $filename) {        // get offset from filename        list($dir, $offset) = explode('.patch.', $filename, 2);        // read patch and close        $patch_contents = Storage::disk('tmp')->get($filename);        // apply patch        Storage::disk('tmp')->append($dir . $name, $patch_contents, "");    }    // remove patches    foreach ($patch as $filename) {        Storage::disk('tmp')->delete($filename);    }}问题是大文件会出现以下错误。"Allowed memory size of 134217728 bytes exhausted (tried to allocate 160000008 bytes)"我知道错误与 append 方法有关。我根据此链接中的解决方案解决了问题,如下所示。// if total size equals length of file we have gathered all patch filesif ($size == $length) {    $time_limit = ini_get('max_execution_time');    $memory_limit = ini_get('memory_limit');    set_time_limit(0);    ini_set('memory_limit', '-1');    // write patches to file    foreach ($patch as $filename) {        // get offset from filename        list($dir, $offset) = explode('.patch.', $filename, 2);        // read patch and close        $patch_contents = Storage::disk('tmp')->get($filename);        // apply patch        Storage::disk('tmp')->append($dir . $name, $patch_contents, "");    }    // remove patches    foreach ($patch as $filename) {        Storage::disk('tmp')->delete($filename);    }    set_time_limit($time_limit);    ini_set('memory_limit', $memory_limit);}但是我对这个解决方案没有很好的感觉!我的问题是,首先,为什么append方法会出现这样的错误呢?解决方案是否合适?另一方面,Laravel 对这个问题的解决方案是什么?
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

根本原因似乎在append的来源。

$this->put($path, $this->get($path).$separator.$data);

这将获取文件内容,然后连接数据并将文件放回原处。不知道为什么这样做,但我猜这是因为所有存储类型都不支持以追加模式打开文件,并且必须Storage实现CloudFilesystemContract这意味着它适用于云存储(你通常不能“追加” " 到一个文件)。

深入挖掘可以发现 Laravel 的“驱动程序”由FlysystemStorage支持,并且其接口中不包含功能,因此 Laravel 只能使用提供的接口方法来实现一个功能。append

您始终可以推出自己的解决方案:

// if total size equals length of file we have gathered all patch files

if ($size == $length) {

    // write patches to file

    foreach ($patch as $filename) {

        // get offset from filename

        list($dir, $offset) = explode('.patch.', $filename, 2);


        // read patch and close

        $patch_contents = Storage::disk('tmp')->get($filename);


        // apply patch

        $fhandle = fopen($dir.$name, "a"); // You may need to adjust the filename 

        fwrite($fhandle, $patch_contents);

        fclose($fhandle);

    }


    // remove patches

    foreach ($patch as $filename) {

        Storage::disk('tmp')->delete($filename);

    }

}


查看完整回答
反对 回复 2023-03-26
  • 1 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信