处理大文件或多个文件时,file_put_contents太慢

时间:2018-12-19 00:44:42

标签: php arrays base64

我正在使用 file_put_contents 创建视频文件。问题是速度和性能。创建平均大小为50 mb的文件平均大约需要30到60分钟,而仅一个文件即可。我正在解码字节数组以创建文件。如何提高速度和性能?

$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$Video = $json_obj->Video;
$CAF = $json_obj->CAF;
$Date = $json_obj->Date;
$CafDate = date("Y-m-d", strtotime($Date));

$video_decode = base64_decode($Video);
$video_filename = __DIR__ . '/uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$video_dbfilename = './uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$save_video = file_put_contents($video_filename, $video_decode);

2 个答案:

答案 0 :(得分:1)

当无法预知大小或将要处理大文件时,请勿将整个文件加载到内存中。最好分块读取文件并逐块处理它。

下面是一个简单而又肮脏的示例:

<?php
// open the handle in binary-read mode
$handle = fopen("php://input", "r");

// open handle for saving the file
$local_file = fopen("path/to/file", "w");

// create a variable to store the chunks
$chunk = '';

// loop until the end of the file
while (!feof($handle)) {
  // get a chunk
  $chunk = fread($handle, 8192);

  // here you do whatever you want with $chunk
  // (i.e. save it appending to some file)
  fwrite($local_file, $chunk);
}

// close handles
fclose($handle);
fclose($local_file);

答案 1 :(得分:0)

这里有很多问题,具有复利效果。

$json_str = file_get_contents('php://input');

这会将整个输入读入内存,并阻塞直到完成。不要这样做。

$json_obj = json_decode($json_str);

如果您有50MB的JSON,则可能是您做错了。

$Video = $json_obj->Video;

这是您在做的错误...将较大的二进制blob以较小的结构化数据序列化格式存储。您意识到JSON解析器必须读取并处理整个事情吗?不要为此发送JSON!

$video_decode = base64_decode($Video);

除非绝对必要,否则请不要使用base-64编码。它将存储容量以及用于编码/解码的CPU的开销增加了33%。这是完全浪费,完全没有必要。

$video_filename = __DIR__ . '/uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$video_dbfilename = './uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';

这两行可能存在严重的安全问题。如果有人发布了../../../etc/init.d/something-evil的路径怎么办?不要让用户以任何方式指定磁盘上的文件名。

$save_video = file_put_contents($video_filename, $video_decode);

file_get_contents()中的注释在这里适用,因为您应该使用此方法。而是将内容流式传输到磁盘。