PhpSpreadsheet: Permissions | ZipArchive::close(): Failure to create temporary file

前端 未结 3 599
梦毁少年i
梦毁少年i 2021-01-18 10:53

I would like to offer an Excel-File for download with PhpSpreadsheet

Here is my code:

    require \'vendor/autoload.php\';

    use PhpOffice\\PhpSpr         


        
相关标签:
3条回答
  • The issue was the tmp directory used by phpSpreadSheet and that was not writable by PHP process. I changed the tmp directory to upload tmp directory and now the issue is resolved. I solved the issue using

    \PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);
    
    0 讨论(0)
  • 2021-01-18 11:27

    General rules for a directory in PHP to write to it:

    It must exist,

    It is writable by PHP process,

    It is allowed by open_basedir php.ini directive.

    Therefore, set some file path as argument in the $writer->save() method and check that these 3 rules are met.

    If you want to use only php://output or php://stdout value in the $writer->save() method, check these rules for:

    1) The directory returned by the sys_get_temp_dir() function. In Windows sys_get_temp_dir() by default returns the temporary directory of the current OS user. The value can be changed by sys_temp_dir php.ini directive.

    or

    2) The directory returned by the upload_tmp_dir php.ini directive. $useUploadTempDirectory has false value by default. To set it value to true add this line in your code before saving the file:

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


    Here is the code that is responsible for selecting the save path:

    From \PhpOffice\PhpSpreadsheet\Writer\Xlsx::save method (source):

    // 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;
        }
    }
    

    From \PhpOffice\PhpSpreadsheet\SharedFile::sysGetTempDir method (source):

    /**
     * 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());
    }
    
    0 讨论(0)
  • 2021-01-18 11:32

    I don't know if your code is from an included file but I had a similar issue. I tried to use __DIR__ constant and it worked, my code looks like this:

    $filepath = __DIR__ . "/reports/${filename}_".date("Ymd_Gis").".xlsx";
    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
    $writer->save($filepath);
    
    0 讨论(0)
提交回复
热议问题