PHP使用fwrite和fread与输入流

时间:2012-03-07 03:58:23

标签: php inputstream

我正在寻找将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脚本的内存中保存文件的内容

我正在寻找类似但相反的东西(将输入流写入文件)。感谢您提供任何帮助。

1 个答案:

答案 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正在使用的任何内存。