我正在寻找将PHP输入流的内容写入磁盘的最有效方法,而不使用授予PHP脚本的大量内存。例如,如果可以上载的最大文件大小为1 GB,但PHP只有32 MB内存。
define('MAX_FILE_LEN', 1073741824); // 1 GB in bytes
$hSource = fopen('php://input', 'r');
$hDest = fopen(UPLOADS_DIR.'/'.$MyTempName.'.tmp', 'w');
fwrite($hDest, fread($hSource, MAX_FILE_LEN));
fclose($hDest);
fclose($hSource);
像上面代码那样的fwrite中的fread是否意味着整个文件将被加载到内存中?
为了做相反的事情(将文件写入输出流),PHP提供了一个名为fpassthru的函数,我相信它不会在PHP脚本的内存中保存文件的内容
我正在寻找类似但相反的东西(将从输入流写入文件)。感谢您提供任何帮助。
答案 0 :(得分:5)
是的 - 以这种方式使用的fread
首先会在字符串中读取最多1 GB,然后通过fwrite
将其写回。 PHP只是不够智能,无法为您创建一个内存效率高的管道。
我会尝试类似于以下内容:
$hSource = fopen('php://input', 'r');
$hDest = fopen(UPLOADS_DIR . '/' . $MyTempName . '.tmp', 'w');
while (!feof($hSource)) {
/*
* I'm going to read in 1K chunks. You could make this
* larger, but as a rule of thumb I'd keep it to 1/4 of
* your php memory_limit.
*/
$chunk = fread($hSource, 1024);
fwrite($hDest, $chunk);
}
fclose($hSource);
fclose($hDest);
如果你想要非常挑剔,你也可以在unset($chunk);
之后的循环内fwrite
来绝对确保PHP释放内存 - 但这不是必需的,因为下一个循环将覆盖当时$chunk
正在使用的任何内存。