Медиа-файл может быть огромным, поэтому вы не можете обработать его с помощью методов, которые включают загрузку всего файла в ОЗУ, не говоря уже о нескольких копиях данных одновременно.Ваш код делает это несколько раз.
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$Video = $json_obj->Video;
$video_decode = base64_decode($Video);
На данный момент у вас есть 4 копии видео, загруженные в ОЗУ.Для медиа-файла 50 МБ это означает, что $video_decode
содержит 50 МБ данных, а другие переменные еще больше.Вам также необходимо добавить внутреннюю память, используемую такими функциями, как json_decode()
.Чтобы получить представление об используемой оперативной памяти, вы можете вставить ее между каждой операцией:
var_dump(memory_get_usage(true));
Кроме того, современные видеокодеки представляют собой высоко оптимизированные двоичные потоки.Если вы преобразуете эти двоичные данные в обычный текст, размер будет расти.Base64 увеличивает объем данных на 4/3 .JSON добавляет немного накладных расходов, хотя на данный момент ничего серьезного.
Если бы мне пришлось разработать это с нуля, я бы использовал POST-запрос с двоичным форматом (либо multipart/form-data
или пользовательскую кодировку, может быть, просто файл как есть), а затем просто прочитайте ввод в виде кусков:
Если вы предпочитаете или должны придерживаться текущего дизайна, вам нужноадресация всех операций чтения и декодирования файла в чанках:
И последнее, но не менее важное: никогда не создавайте код SQL путем внедренияненадежный внешний ввод:
$sql = "UPDATE tblCaf SET Video = '$video_dbfilename' WHERE CAFNo = '$CAFNo'";
Вместо этого используйте подготовленные операторы .Орды учебных пособий, которые предлагают иначе, должны были быть сожжены давно.
Обновление: Кажется, что концепция обработки данных небольшими порциями (вместо загрузки всего в памяти)Это не так просто, как я думал, поэтому я приведу исполняемый код, чтобы проиллюстрировать разницу.
Прежде всего, давайте создадим файл размером 100 МБ для проверки:
$test = __DIR__ . '/test.txt';
$fp = fopen($test, 'wb') or die(1);
for ($i = 0; $i < 1839607; $i++) {
fwrite($fp, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n") or die(2);
}
fclose($fp);
Если выприбегнуть к простым в использовании вспомогательным функциям с одним вкладышем:
ini_set('memory_limit', '300M');
$test = __DIR__ . '/test.txt';
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
$data = file_get_contents($test);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
file_put_contents(__DIR__ . '/copy.txt', $data);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
printf("Maximum memory usage: %d MB\n", memory_get_peak_usage(true) / 1024 / 1024);
... это связано с ценой, требующей потенциально большого объема памяти (бесплатной еды не бывает):
Current memory usage: 0 MB
Current memory usage: 100 MB
Current memory usage: 100 MB
Maximum memory usage: 201 MB
Если вы разбили файл на маленькие кусочки:
$test = __DIR__ . '/test.txt';
$chunk_size = 1024 * 1024;
$input = fopen($test, 'rb') or die(1);
$output = fopen(__DIR__ . '/copy.txt', 'wb') or die(2);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
while (!feof($input)) {
$chunk = fread($input, $chunk_size) or die(3);
fwrite($output, $chunk) or die(4);
}
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
fclose($input);
fclose($output);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
printf("Maximum memory usage: %d MB\n", memory_get_peak_usage(true) / 1024 / 1024);
... вы можете использовать фиксированный объем памяти для файлов любого размера:
Current memory usage: 0 MB
Current memory usage: 1 MB
Current memory usage: 1 MB
Maximum memory usage: 3 MB