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

Laravel图片评论功能实现咨询:附评论表与图片表结构

实现Laravel图片画廊的评论功能

嘿,你已经迈出了实现评论功能的第一步!我来帮你把这个功能完整落地,一步步来:

1. 完善数据库迁移(补全外键约束)

你的comments表迁移已经有了基础字段,但还需要添加外键约束来确保数据关联的完整性,同时补全photos表的迁移(假设你需要基础的图片字段):

补全/修改comments表迁移

public function up() {
    Schema::create('comments', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('user_id')->index();
        $table->unsignedInteger('photo_id')->index();
        $table->text('body'); // 这里不需要指定190长度,text类型默认足够,若要限制可以用string(190)
        $table->timestamps();

        // 添加外键约束,确保关联数据删除时评论同步处理
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('photo_id')->references('id')->on('photos')->onDelete('cascade');
    });
}

补全photos表迁移(示例)

public function up() {
    Schema::create('photos', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title')->nullable();
        $table->string('path'); // 存储图片路径
        $table->unsignedInteger('user_id')->nullable()->index(); // 如果图片属于某个用户
        $table->timestamps();

        // 可选:添加用户外键(如果你的画廊有用户上传功能)
        if (Schema::hasTable('users')) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
        }
    });
}

执行迁移生效:

php artisan migrate

2. 建立模型关联

在对应的模型里定义关联关系,这样Laravel就能轻松获取图片的评论、评论的作者等数据:

Photo模型(app/Photo.php)

namespace App;

use Illuminate\Database\Eloquent\Model;

class Photo extends Model
{
    // 允许批量赋值的字段
    protected $fillable = ['title', 'path', 'user_id'];

    // 一张图片对应多条评论,按时间倒序排列
    public function comments()
    {
        return $this->hasMany(Comment::class)->orderBy('created_at', 'desc');
    }

    // 可选:图片属于某个用户(如果你的画廊有用户上传功能)
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Comment模型(app/Comment.php)

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $fillable = ['body'];

    // 评论属于一张图片
    public function photo()
    {
        return $this->belongsTo(Photo::class);
    }

    // 评论属于一个用户
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

User模型(app/User.php)

// 添加以下方法,关联用户的所有评论
public function comments()
{
    return $this->hasMany(Comment::class);
}

3. 创建评论提交逻辑

先创建CommentController来处理评论的提交:

php artisan make:controller CommentController

然后在控制器里写store方法:

namespace App\Http\Controllers;

use App\Comment;
use App\Photo;
use Illuminate\Http\Request;

class CommentController extends Controller
{
    public function __construct()
    {
        // 只有登录用户才能评论,未登录会自动跳转到登录页
        $this->middleware('auth');
    }

    public function store(Request $request, Photo $photo)
    {
        // 验证评论内容,限制长度为190字符
        $request->validate([
            'body' => 'required|max:190',
        ]);

        // 关联图片创建评论,自动填充当前登录用户ID
        $photo->comments()->create([
            'body' => $request->body,
            'user_id' => auth()->id(),
        ]);

        // 回到图片详情页并提示成功
        return back()->with('success', '评论发布成功!');
    }
}

在routes/web.php里添加评论提交路由:

// 提交图片评论的路由
Route::post('/photos/{photo}/comments', 'CommentController@store')->name('photos.comments.store');

4. 在视图中添加评论表单和列表

假设你有图片详情页(比如resources/views/photos/show.blade.php),在页面合适位置添加以下内容:

评论表单

<div class="mt-4">
    @auth
        <form action="{{ route('photos.comments.store', $photo) }}" method="POST">
            @csrf
            <div class="form-group">
                <textarea name="body" class="form-control @error('body') is-invalid @enderror" rows="3" placeholder="写下你的评论...">{{ old('body') }}</textarea>
                @error('body')
                    <span class="invalid-feedback" role="alert">
                        <strong>{{ $message }}</strong>
                    </span>
                @enderror
            </div>
            <button type="submit" class="btn btn-primary">发布评论</button>
        </form>
    @else
        <p>请<a href="{{ route('login') }}">登录</a>后发表评论</p>
    @endauth
</div>

评论列表

<div class="mt-5">
    <h5>评论 ({{ $photo->comments->count() }})</h5>
    @foreach($photo->comments as $comment)
        <div class="card mb-2">
            <div class="card-body p-3">
                <div class="d-flex justify-content-between align-items-start">
                    <div>
                        <strong>{{ $comment->user->name }}</strong>
                        <small class="text-muted">{{ $comment->created_at->diffForHumans() }}</small>
                    </div>
                </div>
                <p class="mt-2 mb-0">{{ $comment->body }}</p>
            </div>
        </div>
    @empty
        <p class="text-muted">还没有评论,快来抢沙发吧!</p>
    @endforeach
</div>

最后,优化PhotoController的show方法,预加载评论和作者避免N+1查询:

public function show(Photo $photo)
{
    // 预加载评论及评论作者,提升页面性能
    $photo->load('comments.user');
    return view('photos.show', compact('photo'));
}

这样,你就完整实现了图片画廊的评论功能啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:00:32