You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何在Blade模板展示Amazon S3存储的多张图片

Laravel中S3图片链接转换及Blade渲染实现方案
  • 前置配置校验
    先确认config/filesystems.php中s3磁盘配置正确,.env中已填写完整的S3认证信息:
    AWS_ACCESS_KEY_ID=你的S3密钥ID
    AWS_SECRET_ACCESS_KEY=你的S3密钥
    AWS_DEFAULT_REGION=存储桶所在区域
    AWS_BUCKET=存储桶名称
    AWS_USE_PATH_STYLE_ENDPOINT=false
    
    如果存储桶是公共读权限,直接生成永久链接即可;如果是私有桶,生成带签名的临时链接即可。
  • 模型层统一处理链接转换(推荐,集合/单条查询自动生效)
    在Book模型中定义cover字段的访问器,所有查询结果取cover属性时会自动转换为可访问链接,无需手动遍历集合处理:
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Casts\Attribute;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Support\Facades\Storage;
    
    class Book extends Model
    {
        /**
         * 自动转换cover字段为S3可访问链接
         */
        protected function cover(): Attribute
        {
            return Attribute::make(
                get: function (?string $value) {
                    // 空值兜底默认封面
                    if (empty($value)) {
                        return asset('static/default-book-cover.png');
                    }
                    // 已经是完整链接直接返回,避免重复拼接
                    if (str_starts_with($value, 'http')) {
                        return $value;
                    }
                    // 公共读桶返回永久访问链接
                    if (config('filesystems.disks.s3.visibility') === 'public') {
                        return Storage::disk('s3')->url($value);
                    }
                    // 私有桶返回24小时有效期的临时签名链接
                    return Storage::disk('s3')->temporaryUrl($value, now()->addDay());
                }
            );
        }
    }
    
  • 控制器查询逻辑
    正常查询Book数据即可,不管是调用get()返回集合,还是调用paginate()返回分页结果,cover字段都会自动完成链接转换:
    <?php
    
    namespace App\Http\Controllers;
    
    use App\Models\Book;
    use Illuminate\View\View;
    
    class BookController extends Controller
    {
        public function list(): View
        {
            // 示例查询12条/页的图书数据
            $books = Book::latest()->paginate(12);
            return view('book.list', compact('books'));
        }
    }
    

    不推荐在控制器中手动遍历集合拼接链接:这种方式复用性差,其他接口/页面查询Book数据时需要重复写拼接逻辑,维护成本高。如果临时需要处理,可通过集合map方法实现:

    $books = Book::get()->map(fn($book) => [
        'id' => $book->id,
        'title' => $book->title,
        'cover' => Storage::disk('s3')->url($book->cover)
    ]);
    
  • Blade模板渲染图片
    直接遍历传入的图书集合,输出img标签即可:
    <div class="grid grid-cols-4 gap-4 p-4">
        @foreach($books as $book)
        <div class="book-card border rounded p-2">
            <h4 class="text-lg font-medium mb-2">{{ $book->title }}</h4>
            <img 
                src="{{ $book->cover }}" 
                alt="{{ $book->title }}图书封面"
                class="w-full h-auto rounded"
                loading="lazy"
            >
        </div>
        @endforeach
    </div>
    
    {{-- 分页渲染 --}}
    <div class="mt-6">
        {{ $books->links() }}
    </div>
    

内容的提问来源于stack exchange,提问作者abik_k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:45:40