ZipArchive проблемы с размером файла и нет такого файла Laravel - PullRequest
0 голосов
/ 27 апреля 2018

Я пытался все время искать решение этой проблемы и старался изо всех сил, но безуспешно. У меня есть проект Laravel, который реализует фотографии, сделанные из хранилища Amazon S3, и мне нужно иметь возможность собрать все фотографии с определенной страницы и сжать их в готовом виде для загрузки. Однако я получаю различные ошибки в зависимости от того, как я его кодирую.

Это то, что у меня сейчас ...

Сначала я инициализирую ZipArchive, а затем открываю проверку на возможные ошибки. Этот код всегда возвращает ответ «Все хорошо».

$zipfile = storage_path() . '/case_photos.zip';
$zip = new ZipArchive;

$ZIP_ERROR = [
    ZipArchive::ER_EXISTS => 'File already exists.',
    ZipArchive::ER_INCONS => 'Zip archive inconsistent.',
    ZipArchive::ER_INVAL => 'Invalid argument.',
    ZipArchive::ER_MEMORY => 'Malloc failure.',
    ZipArchive::ER_NOENT => 'No such file.',
    ZipArchive::ER_NOZIP => 'Not a zip archive.',
    ZipArchive::ER_OPEN => "Can't open file.",
    ZipArchive::ER_READ => 'Read error.',
    ZipArchive::ER_SEEK => 'Seek error.',
];


$result_code = $zip->open($zipfile, ZipArchive::CREATE);
if( $result_code !== true ){
    $msg = isset($ZIP_ERROR[$result_code])? $ZIP_ERROR[$result_code] : 'Unknown error.';
    Log::info("error: " . $msg);
} else {
    Log::info("All good");
}

Затем я проверяю фотографии (сделанные ранее из записей базы данных) и перебираю их, добавляя их одну за другой в ранее открытый архив.

if (!empty($photos)) {
    foreach ($photos as $photo) {
        $sizedPhoto = $this->photoRepo->getPhotoBySize($photo->id, 'large');
        $source = $this->fileStorage->getFileStream($sizedPhoto->storage_name);
        $tmpfname = tempnam(storage_path(), "tmp");
        $destination = fopen($tmpfname, "w");
        while (!feof($source)) {
            fwrite($destination, fread($source,10000));
        }
        fclose($source);
        fclose($destination);
        $zip->addFile($tmpfname, 'photo-'.$photo->id.'.jpg');
        unlink($tmpfname);
    }

    $zip->close();

Однако в строке $zip-close() выдается следующая ошибка:

ZipArchive :: close (): не удается открыть файл: такого файла или каталога нет

Ради тестирования я комментирую эту строку и перехожу к части загрузки:

$response = new StreamedResponse();
$response->setCallback(function () use($zipfile){
    readfile($zipfile);
    unlink($zipfile);
});


$response->headers->set('Content-Type', 'application/x-zip-compressed');
$response->headers->set('Cache-Control', '');
$response->headers->set('Content-Length', filesize($zipfile));
$response->headers->set('Last-Modified', gmdate('D, d M Y H:i:s'));
$contentDisposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, basename($zipfile));
$response->headers->set('Content-Disposition', $contentDisposition);

return $response;

Но тогда я получаю эту ошибку:

filesize (): сбой статистики для /home/vagrant/webapp/storage/case_photos.zip

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

Я хотел использовать размер каждой фотографии в этой строке:

fwrite($destination, fread($source,10000));

Вместо жесткого кодирования ограничение в 10000, но я не могу заставить что-либо работать.

Это очень расстраивает, потому что кажется, что что бы я ни делал, я получаю ошибку 500 с другой проблемой, которую не могу решить. Любая помощь с этим будет принята с благодарностью.

1 Ответ

0 голосов
/ 27 апреля 2018

ОК, так что я узнал, что это было. Оказывается, что файлы tmp были отсоединены до того, как они были добавлены в zip-файл, поэтому, по сути, конечный zip-файл был пустым / 0kb, поэтому он не считывал размер файла и, следовательно, почему он не смог закрыть zip-файл. .

...