猿问

Storage::append() 中“Allowed memory size

我用 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方法会出现这样的错误呢?

解决方案是否合适?

另一方面,Laravel 对这个问题的解决方案是什么?


千巷猫影
浏览 81回答 1
1回答

墨色风雨

根本原因似乎在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 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        $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);    }}
随时随地看视频慕课网APP
我要回答