PhpSpreadsheet:权限 | ZipArchive::close(): 创建临时文件失败
PhpSpreadsheet: Permissions | ZipArchive::close(): Failure to create temporary file
我想提供一个 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
dokumentation of PHPSpreadsheet 说:
\PhpOffice\PhpSpreadsheet\Writer\Xlsx uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location.
upload_tmp_dir是:/Applications/XAMPP/xamppfiles/temp/
我必须检查哪些文件夹权限?
或者是什么导致了问题?
PHP 中目录写入的一般规则:
必须存在,
可由PHP进程写入,
open_basedirphp.ini指令允许
因此,在 $writer->save()
方法中设置一些文件路径作为参数,并检查是否满足这 3 个规则。
如果您只想在 $writer->save()
方法中使用 php://output
或 php://stdout
值,请检查以下规则:
1) sys_get_temp_dir()
函数返回的目录。在 Windows sys_get_temp_dir()
默认情况下 returns 当前 OS 用户的临时目录。该值可以通过 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
方法(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;
}
}
来自\PhpOffice\PhpSpreadsheet\SharedFile::sysGetTempDir
方法(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());
}
我不知道您的代码是否来自包含的文件,但我遇到了类似的问题。我尝试使用 __DIR__
常量并且有效,我的代码如下所示:
$filepath = __DIR__ . "/reports/${filename}_".date("Ymd_Gis").".xlsx";
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($filepath);
问题出在 phpSpreadSheet 使用的 tmp 目录,PHP 进程无法写入该目录。我将 tmp 目录更改为上传 tmp 目录,现在问题已解决。我使用
解决了这个问题
\PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);
我想提供一个 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
dokumentation of PHPSpreadsheet 说:
\PhpOffice\PhpSpreadsheet\Writer\Xlsx uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location.
upload_tmp_dir是:/Applications/XAMPP/xamppfiles/temp/
我必须检查哪些文件夹权限? 或者是什么导致了问题?
PHP 中目录写入的一般规则:
必须存在,
可由PHP进程写入,
open_basedirphp.ini指令允许
因此,在 $writer->save()
方法中设置一些文件路径作为参数,并检查是否满足这 3 个规则。
如果您只想在 $writer->save()
方法中使用 php://output
或 php://stdout
值,请检查以下规则:
1) sys_get_temp_dir()
函数返回的目录。在 Windows sys_get_temp_dir()
默认情况下 returns 当前 OS 用户的临时目录。该值可以通过 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
方法(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;
}
}
来自\PhpOffice\PhpSpreadsheet\SharedFile::sysGetTempDir
方法(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());
}
我不知道您的代码是否来自包含的文件,但我遇到了类似的问题。我尝试使用 __DIR__
常量并且有效,我的代码如下所示:
$filepath = __DIR__ . "/reports/${filename}_".date("Ymd_Gis").".xlsx";
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($filepath);
问题出在 phpSpreadSheet 使用的 tmp 目录,PHP 进程无法写入该目录。我将 tmp 目录更改为上传 tmp 目录,现在问题已解决。我使用
解决了这个问题\PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);