я использую file_put_contents создать видео файл. проблема в скорости и производительности. Создание среднего размера файла 50 МБ занимает в среднем от 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);
Вы не должны загружать целые файлы в память, когда вы не можете предвидеть размер или когда он собирается обрабатывать огромные файлы. Лучше читать файл порциями и обрабатывать его порциями.
Вот быстрый и грязный пример того, как этого добиться:
<?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);
Здесь много проблем, с эффектом наложения.
$json_str = file_get_contents('php://input');
Это читает весь ввод в память, и блокирует, пока не будет сделано. Не делай этого.
$json_obj = json_decode($json_str);
Если у вас есть 50 МБ JSON, вы, вероятно, делаете что-то не так.
$Video = $json_obj->Video;
Это то, что вы делаете неправильно … храните большой двоичный двоичный объект в небольшом формате сериализации структурированных данных. Вы понимаете, что анализатор JSON должен читать и обрабатывать все это? Не отправляйте JSON для этого!
$video_decode = base64_decode($Video);
Не используйте кодировку base-64 без крайней необходимости. Это добавляет 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()
применяется здесь в том, что вы должны использовать этот метод. Вместо этого передайте содержимое на диск.