如何在Laravel模型中添加校验阻止删除(含Laravel 5.3场景)
让我来一步步帮你解决这两个Laravel的问题:
1. 如何在Laravel模型中添加校验逻辑,以阻止执行删除操作?
Laravel的模型内置了删除前事件钩子(deleting),这是添加删除校验的最佳切入点——它会在删除操作执行前触发,你可以在这里编写自定义校验规则,一旦不满足就终止删除。
具体实现步骤:
- 在目标模型中重写
boot方法(必须调用父类的boot方法,否则默认模型事件会失效) - 注册
deleting事件回调,在回调中编写你的校验逻辑 - 校验不通过时,推荐抛出异常(能明确传递错误原因),或者直接返回
false来阻止删除
举个实际例子:假设我们有一个User模型,要阻止标记为"管理员"的用户被删除:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { protected static function boot() { parent::boot(); // 注册删除前校验逻辑 static::deleting(function ($user) { // 自定义校验:检查是否是管理员 if ($user->is_admin === true) { // 抛出异常,调用方可以捕获并处理错误信息 throw new \RuntimeException('管理员账号不允许被删除'); // 也可以直接返回false,但无法传递具体错误原因,不如抛出直观 // return false; } }); } }
这样,当你调用$user->delete()或者User::destroy($id)时,都会触发这个校验,管理员用户的删除操作会直接被终止。
2. 在Laravel 5.3版本中,如何添加校验来阻止数据库内任意数据行的删除?
这个需求分两种常见场景,我分别给出解决方案:
场景一:阻止某个特定模型的所有数据删除
如果只是针对某一个模型(比如Post),不让它的任何数据被删除,直接在该模型的deleting事件里拦截即可:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected static function boot() { parent::boot(); static::deleting(function ($post) { throw new \RuntimeException('该模型的所有数据均禁止删除'); // 或者 return false; }); } }
场景二:全局阻止所有模型的数据删除
如果要让整个系统的所有模型都不能删除数据,可以创建一个基础模型类,让所有业务模型继承它,然后在基础模型里统一注册拦截逻辑:
- 创建基础模型:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class BaseModel extends Model { protected static function boot() { parent::boot(); // 全局拦截所有删除操作 static::deleting(function ($model) { throw new \RuntimeException('系统禁止任何数据删除操作'); }); } }
- 让所有业务模型继承
BaseModel(替换默认的Model):
<?php namespace App; // 继承自定义的BaseModel class User extends BaseModel { // ... 模型的其他业务代码 }
针对Laravel 5.3的注意事项
- 上述方案仅针对模型层面的删除操作(比如
$model->delete()、Model::destroy()),如果你直接使用查询构造器删除(比如DB::table('users')->where('id', 1)->delete()),不会触发模型的deleting事件。如果要拦截这种情况,建议在应用层面规范操作,统一使用模型方法删除,或者在数据库层面添加删除触发器。 - Laravel 5.3已经支持模型观察者,但直接在
boot方法里注册事件是最直接的实现方式,不需要额外创建观察者类。
内容的提问来源于stack exchange,提问作者Jenski
相关产品推荐
相关产品推荐

