15

我有一个 PHP 脚本,偶尔需要将大文件写入磁盘。使用file_put_contents(),如果文件足够大(在本例中约为 2 MB),PHP 脚本会耗尽内存(PHP 致命错误:允许的内存大小为 ######## 字节已用完)。我知道我可以增加内存限制,但这对我来说似乎不是一个完整的解决方案——必须有更好的方法,对吧?

在 PHP 中将大文件写入磁盘的最佳方法是什么?

4

3 回答 3

18

您需要一个临时文件,在其中放置源文件的部分内容以及要附加的内容:

$sp = fopen('source', 'r');
$op = fopen('tempfile', 'w');

while (!feof($sp)) {
   $buffer = fread($sp, 512);  // use a buffer of 512 bytes
   fwrite($op, $buffer);
}

// append new data
fwrite($op, $new_data);    

// close handles
fclose($op);
fclose($sp);

// make temporary file the new source
rename('tempfile', 'source');

这样, 的全部内容source就不会被读入内存。使用 cURL 时,您可以省略设置CURLOPT_RETURNTRANSFER,而是添加一个写入临时文件的输出缓冲区:

function write_temp($buffer) {
     global $handle;
     fwrite($handle, $buffer);
     return '';   // return EMPTY string, so nothing's internally buffered
}

$handle = fopen('tempfile', 'w');
ob_start('write_temp');

$curl_handle = curl_init('http://example.com/');
curl_setopt($curl_handle, CURLOPT_BUFFERSIZE, 512);
curl_exec($curl_handle);

ob_end_clean();
fclose($handle);

似乎我总是错过显而易见的事情。正如 Marc 所指出的CURLOPT_FILE,直接将响应写入磁盘。

于 2011-01-25T19:40:41.527 回答
1

使用如下函数逐行写入(或在二进制文件的情况下逐包写入)fwrite()

于 2011-01-25T19:40:31.443 回答
0

试试这个答案

    $file   = fopen("file.json", "w");

    $pieces = str_split($content, 1024 * 4);
    foreach ($pieces as $piece) {
        fwrite($file, $piece, strlen($piece));
    }

    fclose($file);
于 2015-11-04T09:22:33.307 回答