我正在寻找将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);
Run Code Online (Sandbox Code Playgroud)
像上面的代码一样在fwrite中显示是否意味着整个文件将被加载到内存中?
做相反(将文件写入到输出流),PHP提供了一个函数调用fpassthru我认为不成立的PHP脚本的内存中的文件的内容.
我正在寻找类似但相反的东西(从输入流写入文件).感谢您提供任何帮助.
小智 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);
Run Code Online (Sandbox Code Playgroud)
如果你想要非常挑剔,你也可以unset($chunk);在循环之后fwrite绝对确保PHP释放内存 - 但这不是必需的,因为下一个循环将覆盖$chunk当时正在使用的任何内存.