From afc87ef32c1f43e30bcd83c19f3f64f7273b1bd0 Mon Sep 17 00:00:00 2001 From: lion <120344285@qq.com> Date: Tue, 14 Apr 2026 00:17:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Api/H5UploadController.php | 11 ++--- app/Http/Controllers/Api/UploadController.php | 16 +++---- .../StoresPublicUploadWithoutFileinfo.php | 42 +++++++++++++++++++ 3 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 app/Http/Controllers/Concerns/StoresPublicUploadWithoutFileinfo.php diff --git a/app/Http/Controllers/Api/H5UploadController.php b/app/Http/Controllers/Api/H5UploadController.php index 277f62b..1285d90 100644 --- a/app/Http/Controllers/Api/H5UploadController.php +++ b/app/Http/Controllers/Api/H5UploadController.php @@ -3,17 +3,18 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Concerns\EnsuresPublicDiskWritable; +use App\Http\Controllers\Concerns\StoresPublicUploadWithoutFileinfo; use App\Http\Controllers\Controller; use App\Models\WechatUser; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Storage; use Throwable; class H5UploadController extends Controller { use EnsuresPublicDiskWritable; + use StoresPublicUploadWithoutFileinfo; public function store(Request $request): JsonResponse { @@ -36,12 +37,12 @@ class H5UploadController extends Controller } $data = $request->validate([ - 'file' => ['required', 'file', 'max:5120', 'mimes:jpg,jpeg,png,gif,webp'], + // mimes 内部用 guessExtension(),依赖 fileinfo;extensions 仅看客户端扩展名 + 'file' => ['required', 'file', 'max:5120', 'extensions:jpg,jpeg,png,gif,webp'], ]); try { - Storage::disk('public')->makeDirectory('uploads/h5'); - $path = Storage::disk('public')->putFile('uploads/h5', $data['file']); + $path = $this->storeUploadedFileAsUniqueName($data['file'], 'uploads/h5'); } catch (Throwable $e) { report($e); Log::error('h5_upload_putfile_failed', [ @@ -62,7 +63,7 @@ class H5UploadController extends Controller return response()->json([ 'message' => '文件保存失败(写入返回失败)', - 'detail' => config('app.debug') ? 'Storage::putFile 返回 false' : null, + 'detail' => config('app.debug') ? 'Storage::putFileAs 返回 false' : null, ], 500); } diff --git a/app/Http/Controllers/Api/UploadController.php b/app/Http/Controllers/Api/UploadController.php index c216325..2809eaa 100644 --- a/app/Http/Controllers/Api/UploadController.php +++ b/app/Http/Controllers/Api/UploadController.php @@ -3,16 +3,17 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Concerns\EnsuresPublicDiskWritable; +use App\Http\Controllers\Concerns\StoresPublicUploadWithoutFileinfo; use App\Http\Controllers\Controller; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Storage; use Throwable; class UploadController extends Controller { use EnsuresPublicDiskWritable; + use StoresPublicUploadWithoutFileinfo; public function store(Request $request): JsonResponse { @@ -38,8 +39,7 @@ class UploadController extends Controller ]); try { - Storage::disk('public')->makeDirectory('uploads'); - $path = Storage::disk('public')->putFile('uploads', $data['file']); + $path = $this->storeUploadedFileAsUniqueName($data['file'], 'uploads'); } catch (Throwable $e) { report($e); Log::error('upload_putfile_failed', [ @@ -64,18 +64,12 @@ class UploadController extends Controller ], 500); } - try { - $mime = $data['file']->getMimeType() - ?: $data['file']->getClientMimeType() - ?: 'application/octet-stream'; - } catch (Throwable) { - $mime = 'application/octet-stream'; - } + $mime = self::jsonSafeString($this->mimeForUploadResponse($data['file'])); return response()->json([ 'path' => $path, 'url' => url('/storage/'.str_replace('\\', '/', $path)), - 'mime' => self::jsonSafeString($mime), + 'mime' => $mime, 'size' => $data['file']->getSize(), ]); } diff --git a/app/Http/Controllers/Concerns/StoresPublicUploadWithoutFileinfo.php b/app/Http/Controllers/Concerns/StoresPublicUploadWithoutFileinfo.php new file mode 100644 index 0000000..1a953a2 --- /dev/null +++ b/app/Http/Controllers/Concerns/StoresPublicUploadWithoutFileinfo.php @@ -0,0 +1,42 @@ +guessExtension(),会触发 finfo。 + */ +trait StoresPublicUploadWithoutFileinfo +{ + protected function storeUploadedFileAsUniqueName(UploadedFile $file, string $directory): string|false + { + $ext = strtolower($file->getClientOriginalExtension()); + $name = Str::uuid()->toString(); + if ($ext !== '') { + $name .= '.'.$ext; + } + + Storage::disk('public')->makeDirectory($directory); + + return Storage::disk('public')->putFileAs($directory, $file, $name); + } + + /** 无 fileinfo 时仅用客户端声明的 MIME,避免调用 getMimeType() */ + protected function mimeForUploadResponse(UploadedFile $file): string + { + if (class_exists(\finfo::class)) { + try { + return $file->getMimeType() + ?: $file->getClientMimeType() + ?: 'application/octet-stream'; + } catch (\Throwable) { + // fallthrough + } + } + + return $file->getClientMimeType() ?: 'application/octet-stream'; + } +}