Php Laravel解决方案;允许的内存大小为134217728字节,已耗尽“;存储中出错::append()

Php Laravel解决方案;允许的内存大小为134217728字节,已耗尽“;存储中出错::append(),php,laravel,Php,Laravel,我用Laravel实现了一个代码来处理区块上传,如下所示 // 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, $offs

我用Laravel实现了一个代码来处理区块上传,如下所示

// 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
        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 files
if ($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方法会导致这样的错误
  • 这个解决方案合适吗
  • 另一方面,拉威尔对这个问题的解决方案是什么

根本原因似乎在源头

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

深入挖掘可以发现,Laravel的
存储
“驱动程序”由支持,并且在其接口中不包括
附加
功能,因此Laravel必须仅使用提供的接口方法实现一个

您可以随时推出自己的解决方案:

// 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);
    }
}
// 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);
    }
}