如何基于Laravel 5.5开发带自动分相册功能的图库系统?
实现Laravel 5.5图库系统的分步指南
嘿,这个需求挺常见的,我来一步步给你捋清楚怎么在Laravel 5.5里实现它:
1. 数据库设计
首先得搞定两张核心表:albums(相册表)和photos(照片表)。咱们先写迁移文件:
相册表迁移
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAlbumsTable extends Migration { public function up() { Schema::create('albums', function (Blueprint $table) { $table->increments('id'); $table->string('title'); // 相册标题 $table->unsignedInteger('cover_photo_id')->nullable(); // 封面照片ID $table->timestamps(); }); } public function down() { Schema::dropIfExists('albums'); } }
照片表迁移
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePhotosTable extends Migration { public function up() { Schema::create('photos', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('album_id'); // 关联相册ID $table->string('path'); // 图片存储路径 $table->timestamps(); $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade'); }); } public function down() { Schema::dropIfExists('photos'); } }
运行迁移:php artisan migrate
2. 模型与关联
创建两个模型并设置Eloquent关联:
Album模型(app/Album.php)
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Album extends Model { protected $fillable = ['title', 'cover_photo_id']; // 相册拥有多张照片 public function photos() { return $this->hasMany(Photo::class); } // 获取封面照片 public function coverPhoto() { return $this->belongsTo(Photo::class, 'cover_photo_id'); } }
Photo模型(app/Photo.php)
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Photo extends Model { protected $fillable = ['album_id', 'path']; // 照片属于一个相册 public function album() { return $this->belongsTo(Album::class); } }
3. 路由与控制器逻辑
先定义路由(routes/web.php):
// 展示相册列表 Route::get('/albums', 'AlbumController@index')->name('albums.index'); // 展示上传表单 Route::get('/albums/create', 'AlbumController@create')->name('albums.create'); // 处理上传并创建相册 Route::post('/albums', 'AlbumController@store')->name('albums.store'); // 展示相册详情 Route::get('/albums/{album}', 'AlbumController@show')->name('albums.show');
接下来创建AlbumController:
<?php namespace App\Http\Controllers; use App\Album; use App\Photo; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class AlbumController extends Controller { // 展示所有相册 public function index() { $albums = Album::with('coverPhoto')->get(); return view('albums.index', compact('albums')); } // 展示上传表单 public function create() { return view('albums.create'); } // 处理上传并创建相册 public function store(Request $request) { // 验证输入 $request->validate([ 'title' => 'required|string|max:255', 'photos' => 'required|array', 'photos.*' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048' // 限制图片类型和大小 ]); // 创建相册 $album = Album::create([ 'title' => $request->title ]); // 处理上传的图片 $photos = $request->file('photos'); $firstPhotoId = null; foreach ($photos as $photo) { // 存储图片到storage/app/public/photos目录 $path = $photo->store('photos', 'public'); // 创建照片记录 $photoModel = Photo::create([ 'album_id' => $album->id, 'path' => $path ]); // 记录第一张照片的ID作为封面 if (is_null($firstPhotoId)) { $firstPhotoId = $photoModel->id; } } // 更新相册封面 $album->update(['cover_photo_id' => $firstPhotoId]); // 重定向到相册列表页 return redirect()->route('albums.index')->with('success', '相册创建成功!'); } // 展示相册详情 public function show(Album $album) { $album->load('photos'); return view('albums.show', compact('album')); } }
别忘了创建软链接让public目录能访问storage里的图片:php artisan storage:link
4. 视图文件
现在来写视图,放在resources/views/albums目录下:
相册列表页(index.blade.php)
<!DOCTYPE html> <html> <head> <title>图库系统</title> <style> .album-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; padding: 20px; } .album-card { border: 1px solid #ddd; border-radius: 8px; overflow: hidden; text-decoration: none; color: #333; } .album-cover { width: 100%; height: 200px; object-fit: cover; } .album-title { padding: 10px; text-align: center; font-weight: bold; } </style> </head> <body> <h1>我的相册</h1> <a href="{{ route('albums.create') }}">创建新相册</a> @if(session('success')) <p style="color: green;">{{ session('success') }}</p> @endif <div class="album-grid"> @foreach($albums as $album) <a href="{{ route('albums.show', $album) }}" class="album-card"> <img src="{{ asset('storage/' . $album->coverPhoto->path) }}" alt="{{ $album->title }}" class="album-cover"> <div class="album-title">{{ $album->title }}</div> </a> @endforeach </div> </body> </html>
上传表单页(create.blade.php)
<!DOCTYPE html> <html> <head> <title>创建新相册</title> </head> <body> <h1>创建新相册</h1> <form action="{{ route('albums.store') }}" method="POST" enctype="multipart/form-data"> @csrf <div> <label>相册标题:</label> <input type="text" name="title" value="{{ old('title') }}" required> @error('title') <p style="color: red;">{{ $message }}</p> @enderror </div> <div> <label>选择照片(可多选):</label> <input type="file" name="photos[]" multiple required> @error('photos') <p style="color: red;">{{ $message }}</p> @enderror @error('photos.*') <p style="color: red;">{{ $message }}</p> @enderror </div> <button type="submit">创建相册</button> </form> <a href="{{ route('albums.index') }}">返回相册列表</a> </body> </html>
相册详情页(show.blade.php)
<!DOCTYPE html> <html> <head> <title>{{ $album->title }}</title> <style> .photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; padding: 20px; } .photo-item { width: 100%; height: 150px; object-fit: cover; border-radius: 4px; } </style> </head> <body> <h1>{{ $album->title }}</h1> <a href="{{ route('albums.index') }}">返回相册列表</a> <div class="photo-grid"> @foreach($album->photos as $photo) <img src="{{ asset('storage/' . $photo->path) }}" alt="照片" class="photo-item"> @endforeach </div> </body> </html>
这样一套下来,就实现了你要的功能:每次上传照片时创建新相册,相册展示标题和首张照片,点击相册查看所有照片。你可以根据自己的需求调整样式、验证规则或者存储路径哦。
内容的提问来源于stack exchange,提问作者Anand Mainali
相关产品推荐
相关产品推荐

