38 lines
1.4 KiB
PHP
38 lines
1.4 KiB
PHP
<?php
|
|
namespace app\common\utils\pdf\service;
|
|
|
|
final class PdfStorage
|
|
{
|
|
/**
|
|
* @param string $pdfBin PDF 二进制
|
|
* @param string|null $dir 保存目录,默认 runtime/pdf
|
|
* @param string|null $name 文件名(不含目录),默认:stock-order-YYYYmmdd-His-uniqid.pdf
|
|
* @return string 绝对路径
|
|
*/
|
|
public static function saveBinary(string $pdfBin, ?string $dir = null, ?string $name = null): string
|
|
{
|
|
$dir = $dir ?: runtime_path('pdf');
|
|
if (!is_dir($dir)) {
|
|
if (!@mkdir($dir, 0775, true) && !is_dir($dir)) {
|
|
throw new \RuntimeException("Failed to create dir: {$dir}");
|
|
}
|
|
}
|
|
|
|
// 生成安全文件名
|
|
$name = $name ?: ('stock-order-' . date('Ymd-His') . '-' . substr(uniqid('', true), -6) . '.pdf');
|
|
$name = preg_replace('/[^a-zA-Z0-9_\-.]/', '_', $name); // 简易净化
|
|
$path = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $name;
|
|
|
|
// 先写入临时文件,再原子重命名,避免并发/写入中被读取
|
|
$tmp = $path . '.part';
|
|
if (file_put_contents($tmp, $pdfBin, LOCK_EX) === false) {
|
|
throw new \RuntimeException("Failed to write temp file: {$tmp}");
|
|
}
|
|
if (!@rename($tmp, $path)) {
|
|
@unlink($tmp);
|
|
throw new \RuntimeException("Failed to move temp to: {$path}");
|
|
}
|
|
@chmod($path, 0664);
|
|
return $path;
|
|
}
|
|
} |