php file_get_contents(): содержимое усекается с 2147483648 до 2147483647 байт

Как я могу выяснить проблему, когда я собираюсь создать zip-файл размером 2 ГБ.

Ошибка

file_get_contents(): содержимое усекается с 2147483648 до 2147483647 байт.

Фатальная ошибка: Недостаточно памяти (выделено 2151677952) (попытался выделить 18446744071562067968 байт) в

Я использую выделенный сервер и уже установил memory_limit,max_execution_time,max_upload_filesize,max_post_size. Но у меня это не работает. Пожалуйста, проверьте мой код и дайте мне знать, что я делаю неправильно -

создать новый zip-объект

    $zip = new ZipArchive();

    # create a temp file & open it
    $tmp_file = tempnam('.','');
    $zip->open($tmp_file, ZipArchive::CREATE);

    # loop through each file
    foreach($files as $file){
        # download file
        $download_file = file_get_contents($file_path.'/'.$file);
        #add it to the zip
        $zip->addFromString(basename($file_path.'/'.$file),$download_file);
    }

    # close zip
    $zip->close();
    $zip_name = $last_seg.'.zip';
    # send the file to the browser as a download
    header("Content-disposition: attachment; filename=$zip_name");
    header('Content-type: application/zip');
    readfile($tmp_file);

person Community    schedule 06.04.2015    source источник
comment
Попробуйте это решение, представленное здесь > stackoverflow.com/questions/6282887/ это проблема с ограничением памяти, и ваш файл слишком велик.   -  person    schedule 06.04.2015
comment
Также проверьте этот вопрос/ответ .com/questions/5745255/   -  person    schedule 06.04.2015
comment
возможный дубликат Верхний предел памяти для PHP/Apache   -  person Zulu    schedule 06.04.2015
comment
Большое спасибо, это может быть дублирующий вопрос, но после того, как я попробовал все доступные здесь решения, я задал его снова. Я пытался увеличить лимит памяти из WHM, но не работал :(   -  person    schedule 06.04.2015
comment
Я использую выделенный сервер и уже установил memory_limit, max_execution_time, max_upload_filesize, max_post_size. Но это не работает для меня.   -  person    schedule 08.04.2015
comment
в сообщении говорится, что вы пытаетесь выделить 18446744 TeraBytes. Я думаю, что вам следует не только настроить лимиты памяти, но и купить намного больше оперативной памяти ...   -  person Paolo    schedule 08.04.2015
comment
Как уже говорилось ранее, вы должны использовать потоки для создания zip-файлов. Другой вариант заключается в том, что вы используете внешний двоичный файл для сжатия реальных файлов вместо PHP zip. В любом случае, будьте осторожны при создании архивов для файлов размером более 2 ГБ. Некоторые реализации zip могут иметь проблемы с распаковкой.   -  person Gerd K    schedule 08.04.2015
comment
@jenifer, поскольку вы говорите, что мой ответ решит вашу проблему, не забудьте проверить его как принятый.   -  person Adrian Cid Almaguer    schedule 14.04.2015


Ответы (3)


Я меняю $zip->addFromString() на $zip->addFile(), потому что вам не нужно читать файл содержимого, чтобы добавить файл, я тестирую ваш код с 3 фильмами и не работает (у меня была такая же ошибка), но когда я использую $zip->addFile(), все идет нормально, и я мог скачать zip файл с 3gb.

Мне нужно использовать set_time_limit(0);

Если вы хотите протестировать этот код, измените только значения:

$files //Array of files name $file_path //Path where your files ($files) are placed $last_seg //The name of your zip file

<?php

    set_time_limit(0);

    $files = array('Exodus.mp4', 'the-expert.webm', 'what-virgin-means.webm');
    $file_path = 'zip';
    $last_seg = 'test';

    $zip = new ZipArchive();

    # create a temp file & open it
    $tmp_file = tempnam('.','');
    $zip->open($tmp_file, ZipArchive::CREATE);

    # loop through each file
    foreach($files as $file){
        $zip->addFile($file_path.'/'.$file, $file);
    }

    # close zip
    $zip->close();
    $zip_name = $last_seg.'.zip';
    # send the file to the browser as a download
    header("Content-disposition: attachment; filename=$zip_name");
    header('Content-type: application/zip');
    readfile($tmp_file);

?>

Вы можете прочитать больше на:

http://php.net/manual/en/ziparchive.addfile.php

person Adrian Cid Almaguer    schedule 10.04.2015
comment
@jenifer добро пожаловать, не забудьте проверить, что он принят ;-) Если вы не знаете, как прочитать это stackoverflow.com/tour - person Adrian Cid Almaguer; 10.04.2015
comment
@jenifer помните, примите ответ, помните, что вы говорите, что это работает отлично ;-) - person Adrian Cid Almaguer; 25.04.2015
comment
@jenifer, если вы не знаете, как проверить ответ как принятый, прочитайте это stackoverflow.com/tour - person Adrian Cid Almaguer; 01.05.2015

Вы никогда не сможете выделить больше памяти, чем PHP_INT_MAX. Так что, возможно, версии PHP для Linux x64 могут справиться с этим, если file_gets_content не ограничен внутри 32-битным числом со знаком, но в Windows или в 32-битной системе у вас нет шансов добиться этого без потоковой передачи.

Что-то вроде этого может работать: (еще не проверено)

$fr = fopen("http://...", "r");
$fw = fopen("zip://c:\\test.zip#test", "w");

while(false !== ($buffer = fread($fr, 8192)))
{
  fwrite($fw, $buffer, strlen($buffer));
}

fclose($fr);
fclose($fw);

Хорошо, мой плохой, очевидно, PHP не предоставляет режим "+w" для zip-потока... Тогда вашими последними вариантами будут запись всего файла во временный файл (путем его потоковой передачи, как я, без file_get_contents) перед его передачей во внешнюю программу (с вызовом system() или popen...) или с использованием другого формата сжатия (очевидно, php поддерживает операцию записи потока для zlib ant bzip2) или использовать внешнюю библиотеку для php.

person mathieu    schedule 08.04.2015
comment
спасибо, матье, так что мне нужно изменить свой код? вы знаете, что я должен изменить здесь? или любую ссылку, где я могу найти ссылку? - person ; 08.04.2015
comment
По сути, вам нужно открыть zip-поток для записи в него, а затем повторно прочитать входной файл с буфером, который может обработать php... Я не уверен, что это возможно без внешних библиотек. - person mathieu; 08.04.2015

попробуйте поместить эту строку в начало вашего кода:

ini_set("memory_limit", -1);

Обратитесь к этому вопросу Неустранимая ошибка: Out памяти (выделено 1134559232) (попытался выделить 32768 байт) в X:\wamp\www\xxx

person Manee.O.H    schedule 06.04.2015
comment
хорошо, большое спасибо за ваше драгоценное время, я попробую это. Я уже пробовал memory_limit = -1 на WHM, но это не сработало. - person ; 06.04.2015
comment
-1 Размер 18446744071562067968 превысит системную память. Добавлять больше памяти, чтобы иметь возможность читать файл в память, всегда плохая идея. - person Christian Kuetbach; 08.04.2015