Загрузка Zip PDF-файлов не работает

Я создаю интерфейс, который позволяет собирать PDF-файлы с пути к серверу, чтобы сразу загружать их в заархивированном виде, что в большинстве случаев работает нормально. Теперь некоторые PDF-файлы не работают, это означает, что если zip содержит один из нерабочих файлов, загрузка не будет выполнена.

Теперь я перепробовал много файлов разных размеров. Я могу сказать, что большинство файлов размером более 10 МБ не работают, но один файл (15 МБ) работает, так что это не может быть размер файла, вызывающий эту ошибку, верно?

Что происходит, просто нет загрузки вообще. Дополнительно пробовал читать результаты $zip-›addFile и $zip-›close, но все верно, даже если загрузка не будет выполнена. ЛЮБЫЕ идеи, которые могут вызвать эту ошибку, или хотя бы некоторые намеки на то, как это выяснить?

(x) отладочная проверка переменных во время процесса не отличается между временем, когда оно работало, и временем, когда оно не работало. Различия только в размерах файлов и -путях.

Вот код, который я использую для создания ZIP:

public function downloadFiles() {
        $myFiles = $this->Session->read('Files.MyFiles');
        if(count($myFiles)) {
            // build zip
            $zipname = 'amaz_photos_' . time() . '.zip';
            $zip = new ZipArchive();
            $zip->open($zipname, ZipArchive::CREATE);
            foreach($myFiles as $file) {
                if($file['type'] == 'directory') {
                    $dirName = str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/'))));
                    $zip->addEmptyDir($dirName);
                    $this->addFolderToZip($file['path'] . '/', $zip, $dirName . '/');
                } else {
                    $zip->addFile($file['path'], str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/')))));
                }
            }
            $zip->close();
            // get(send) zip
            header('Content-Type: application/zip');
            header('Content-disposition: attachment; filename=' . $zipname);
            header('Content-Length: ' . filesize($zipname));
            readfile($zipname);
            ignore_user_abort(true);
            unlink($zipname);
        }

        // clear "myFiles"
        //$this->Session->write('Files.MyFiles', array());

        $this->redirect(array(
            'controller' => 'pages',
            'action' => 'display'
        ));
    }

В конце концов, я пытался открыть поврежденные файлы с помощью нескольких PDF-ридеров, включая оригинал Adobe, чтобы определить, не сломан ли он, но ̶i̶̶t̶̶s̶ похоже, что нет.

Это происходит с открываемыми zip-файлами, но загрузка все равно не начинается. Я обнаружил, что в тех особых случаях, когда загрузка не начинается, в сетевом фрейме не устанавливается заголовок ответа (приложение/zip) по сравнению со временем, когда он работал.

Что я еще узнал: Допустим, у меня есть папка с 20 файлами, которые не загружаются. Пробовал выбирать файл 1-10: загружается, потом пробовал скачивать файл 11-20: скачивал, потом пробовал скачивать файл 1-20: не скачивал, потом пробовал два раза смешивать паттерны, сначала четные файлы 2,4 ,6,8.. (1-20), далее нечетные файлы 1,3,5,7,.. (1-20): каждый не скачивается. Это означает, что ошибка не относится к конкретному файлу.

Любые предложения, как определить триггер для этой ошибки?


Обновлять:

Мне удалось загрузить сгенерированный zip-файл, выполнив следующие действия:

  1. Триггер «создать и скачать zip-файл»

  2. Он создает zip-файл, но не загружает его

  3. Введите имя файла сгенерированного zip-файла в код, чтобы загрузить его на следующей процедуре (например, $zipname = generateOnStep1.zip).

  4. Запустите «создать и скачать zip-файл» еще раз

  5. Он загружает не (недавно) сгенерированный файл, а файл, который я сгенерировал на шаге 1. Таким образом, кажется, что: Генерация Zip-файлов работает И загрузка того же самого zip-файла работает, но не сразу и только в каком-то неизвестном комбинации.

...

Обновление 2:

Поскольку я не смог ни определить проблему, ни исправить ее, в итоге я переработал весь процесс, перенаправив его на сгенерированный zip-файл, а не на чтение. Некоторые функции должны были быть получены из источника, но в любом случае это работает так.


person Jonathan    schedule 24.11.2014    source источник
comment
Вы пробовали проверять размер pdf файлов внутри zip? У них есть размер? какой размер по сравнению с исходными файлами. Также вы не дали нам код для addFolderToZip.   -  person user254948    schedule 24.11.2014
comment
В этом случае addFolderToZip() не используется из-за добавления отдельных файлов. Просто пропустите в уме. В любом случае, вы подвели меня к мысли не удалять файл после его загрузки. PDF можно просмотреть, размер на 2 МБ больше, чем не заархивированный. Так вроде все работает нормально но загрузка не начинается. У меня есть большие видеофайлы, которые можно скачать, поэтому я почти уверен, что дело не в ограничениях памяти. Также место на жестком диске совершенно пусто (достаточно).   -  person Jonathan    schedule 24.11.2014
comment
Просто для ясности: ZIP-файл сгенерирован правильно, его можно открыть и просмотреть PDF-файл. Но загрузка не начинается (только) с определенными PDF-файлами.   -  person Jonathan    schedule 24.11.2014
comment
Как часто это происходит, пытались ли вы не удалять сгенерированные zip-файлы, чтобы увидеть, что на самом деле находится внутри zip-файлов или они действительно были созданы? Вы проверили тайм-ауты php (ограничение времени выполнения или ограничение памяти?). Нет загрузки, вы получаете пустую страницу (может указывать на ошибку)? Если это так, проверьте журнал ошибок php/веб-сервера. (кстати, time() уникален только в секунду, будьте осторожны с этим, если 2 запроса выполняются одновременно, это может вызвать проблемы. Возможно, попробуйте tempname).   -  person user254948    schedule 24.11.2014
comment
Да, я пытался сохранить файлы. Это происходит в открываемых zip-файлах, но загрузка все равно не начинается. Я обнаружил, что в тех особых случаях, когда загрузка не начинается, в сетевом фрейме не устанавливается заголовок ответа (приложение/zip) по сравнению со временем, когда он работал. Журнал пуст.   -  person Jonathan    schedule 25.11.2014
comment
какая версия торта?   -  person arilia    schedule 15.03.2016
comment
Я решил проблему, перенаправив в zip-файл вместо readfile его или что-то в этом роде. Это разделяет много логики, но работает так, как ожидалось.   -  person Jonathan    schedule 16.03.2016


Ответы (1)


Попробуйте это... Удалите readfile($zipname); и замените его на это:

/* make sure no other functions
holding this file */
$filehandle = fopen($zipname, "r");

while (!feof($filehandle)) {
  /* lets read the file by pieces and
  send it to user's browser */
  echo fread($filehandle, 8192);
}

fclose($filehandle);

Надеюсь это поможет.

person Ram    schedule 15.03.2016
comment
Это приводит к такому же поведению. Если я заархивирую вручную, он загрузит zip, если я заархивирую с помощью zipArchive, он создаст zip, но не загрузит.. здесь происходит какое-то недетерминированное чудо.. - person Jonathan; 15.03.2016
comment
Даже если ваш ответ не решил мою проблему, он заставил меня изменить процесс, перенаправив файл после создания zip. Спасибо за прод. - person Jonathan; 16.03.2016
comment
Спасибо... Дайте мне знать, если вы решили свою проблему... Я видел, что ваш вопрос был обновлен. Я проведу дальнейшее расследование на основе ваших обновлений и дам вам знать. - person Ram; 16.03.2016