Laravel中如何通过数据库获取的文件名访问文件夹内文件
Looks like you're halfway there—you've got the filenames pulled from the database and passed to your view. Now let's wire up the logic to serve those files correctly (download for zips, inline view for docs/pdfs). Here's a step-by-step solution tailored to your Laravel setup:
First, create a route that will handle requests to serve your files. Add this to your routes/web.php:
Route::get('/serve-file/{filename}', [YourAdminController::class, 'serveFile'])->name('file.serve');
Replace YourAdminController with the name of your existing controller (or create a new FileController if you prefer separation of concerns).
Add this method to your controller to handle whether to download or display the file inline:
use Illuminate\Support\Facades\Storage; use Illuminate\Http\Response; public function serveFile($filename) { // Define your file storage path (adjust if your "File" folder is in public instead of storage) $storagePath = 'File/' . $filename; // Check if the file exists first if (!Storage::disk('public')->exists($storagePath)) { abort(404, 'Requested file not found'); } // Determine file extension to set behavior $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); // Set disposition: inline for viewable files, attachment for zips $disposition = $extension === 'zip' ? 'attachment' : 'inline'; // Serve the file with correct headers return Storage::disk('public')->response( $storagePath, $filename, ['Content-Disposition' => "$disposition; filename=\"$filename\""] ); }
Note: If your "File" folder is directly in the public directory (not storage/app/public), replace the Storage calls with:
$filePath = public_path('File/' . $filename); if (!file_exists($filePath)) abort(404); return response()->file($filePath, [ 'Content-Disposition' => "$disposition; filename=\"$filename\"" ]);
Also, run php artisan storage:link if you're using storage/app/public to make files accessible via the web.
In your admin.RegisterStaff.show blade view, loop through the attachments and create links to the new route:
<div class="attached-files"> <h3>Attached Documents</h3> @if(!empty($attach) && count($attach) > 0) <ul> @foreach($attach as $file) <li> <a href="{{ route('file.serve', ['filename' => $file]) }}" target="_blank"> {{ $file }} </a> </li> @endforeach </ul> @else <p>No files attached.</p> @endif </div>
The target="_blank" will open viewable files (docs, pdfs) in a new tab, while zips will trigger an immediate download.
Always add a check to ensure the user requesting the file has permission to access it. For example, in the serveFile method:
// Get the authenticated user (adjust based on your auth system) $user = auth()->user(); $allowedFiles = explode(",", $user->attachments); if (!in_array($filename, $allowedFiles)) { abort(403, 'Unauthorized access to this file'); }
This prevents attackers from accessing arbitrary files by guessing filenames.
内容的提问来源于stack exchange,提问作者debrata

