You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
szkp-map-service/app/Support/SecurePrivateImportUpload.php

86 lines
2.6 KiB

2 days ago
<?php
namespace App\Support;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use RuntimeException;
/**
* 导入类文件:只进 local 私有盘,禁止写入 public调用方用完须删除。
*/
final class SecurePrivateImportUpload
{
/**
* @param list<string> $allowedExtensions
*/
public static function storeTemporary(
UploadedFile $file,
string $directory,
array $allowedExtensions,
int $maxKilobytes
): string {
if (! $file->isValid()) {
throw ValidationException::withMessages([
'file' => ['上传未通过校验:'.$file->getErrorMessage()],
]);
}
$size = (int) $file->getSize();
if ($size <= 0 || $size > $maxKilobytes * 1024) {
throw ValidationException::withMessages([
'file' => ['文件过大'],
]);
}
$extension = UploadFilenameGuard::lastAllowedExtension(
(string) $file->getClientOriginalName(),
$allowedExtensions
);
$relativeDir = trim(str_replace('\\', '/', $directory), '/');
if ($relativeDir === '' || str_contains($relativeDir, '..')) {
throw new RuntimeException('invalid private import directory');
}
$name = Str::uuid()->toString().'.'.$extension;
$stored = Storage::disk('local')->putFileAs($relativeDir, $file, $name);
if ($stored === false) {
throw new RuntimeException('local disk putFileAs returned false');
}
return storage_path('app/'.ltrim(str_replace('\\', '/', $stored), '/'));
}
/**
* 仅校验、不落盘(调用方使用 PHP 临时文件,如 Excel 预览)。
*
* @param list<string> $allowedExtensions
*/
public static function assertAcceptable(
UploadedFile $file,
array $allowedExtensions,
int $maxKilobytes
): string {
if (! $file->isValid()) {
throw ValidationException::withMessages([
'file' => ['上传未通过校验:'.$file->getErrorMessage()],
]);
}
$size = (int) $file->getSize();
if ($size <= 0 || $size > $maxKilobytes * 1024) {
throw ValidationException::withMessages([
'file' => ['文件过大'],
]);
}
return UploadFilenameGuard::lastAllowedExtension(
(string) $file->getClientOriginalName(),
$allowedExtensions
);
}
}