PhpSpreadsheet: разрешения |ZipArchive :: close (): сбой при создании временного файла - PullRequest
0 голосов
/ 22 мая 2018

Я хотел бы предложить файл Excel для загрузки с помощью PhpSpreadsheet

Вот мой код:

    require 'vendor/autoload.php';

    use PhpOffice\PhpSpreadsheet\Spreadsheet;
    use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', 'Hello World !');

    $writer = new Xlsx($spreadsheet);
    $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');

    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="hello_world.xlsx"');
    $writer->save("php://output");

Я получаю следующее сообщение об ошибке:

    PHP Warning:  ZipArchive::close(): Failure to create temporary file: No such file or directory in /Users/sg/GitWorkingCopies/xxx1/xxx2/library/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php on line 374
    PHP Fatal error:  Uncaught exception 'PhpOffice\PhpSpreadsheet\Writer\Exception' with message 'Could not close zip file php://output.' in /Users/sg/GitWorkingCopies/xxx1/xxx2/library/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php:375

Документация PHPSpreadsheet говорит:

\ PhpOffice \ PhpSpreadsheet \ Writer \ Xlsx использует временное хранилище при записи в выходной файл php: //.По умолчанию временные файлы хранятся в рабочем каталоге скрипта.Когда нет доступа, он возвращается к расположению временных файлов операционной системы.

Файл upload_tmp_dir: /Applications/XAMPP/xamppfiles/temp/

Какие разрешения для папок я должен проверить?Или что вызывает проблему?

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

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

$filepath = __DIR__ . "/reports/${filename}_".date("Ymd_Gis").".xlsx";
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($filepath);
0 голосов
/ 23 мая 2018

Общие правила для каталога в PHP, чтобы написать в него:

Он должен существовать ,

Этодоступен для записи в процессе PHP ,

Это разрешено директивой open_basedir php.ini.

Следовательно, укажите некоторый путь к файлу в качестве аргумента в методе $writer->save() и убедитесь, что эти 3 правила соблюдены.

Если вы хотите использовать только значение php://output или php://stdout в $writer->save()метод, проверьте эти правила для:

1) Каталог, возвращаемый функцией sys_get_temp_dir().В Windows sys_get_temp_dir() по умолчанию возвращает временный каталог текущего пользователя ОС.Значение можно изменить с помощью директивы sys_temp_dir php.ini.

или

2) Каталог, возвращаемый директивой upload_tmp_dir php.ini.$useUploadTempDirectory имеет значение false по умолчанию.Чтобы установить значение true, добавьте эту строку в свой код перед сохранением файла:

\PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);


Вот код, который отвечает за выбор пути сохранения:

Метод \PhpOffice\PhpSpreadsheet\Writer\Xlsx::save ( источник ):

// If $pFilename is php://output or php://stdout, make it a temporary file...
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
    $pFilename = @tempnam(File::sysGetTempDir(), 'phpxltmp');
    if ($pFilename == '') {
        $pFilename = $originalFilename;
    }
}

Метод \PhpOffice\PhpSpreadsheet\SharedFile::sysGetTempDir ( источник ):

/**
 * Get the systems temporary directory.
 *
 * @return string
 */
public static function sysGetTempDir()
{
    if (self::$useUploadTempDirectory) {
        //  use upload-directory when defined to allow 
        // running on environments having very restricted open_basedir configs
        if (ini_get('upload_tmp_dir') !== false) {
            if ($temp = ini_get('upload_tmp_dir')) {
                if (file_exists($temp)) {
                    return realpath($temp);
                }
            }
        }
    }
    return realpath(sys_get_temp_dir());
}
...