Laravel’s DB Facade Doesn’t Trigger Eloquent ORM Model Events

When using the DB facade to perform database operations in Laravel, Eloquent ORM model events like saving, saved, etc., are not triggered.

If you want to avoid triggering model events in event listeners or queued tasks, aside from using Eloquent’s saveQuietly, deleteQuietly, and similar methods, you can directly use the DB facade to execute database operations.

This approach allows you to bypass Eloquent’s event handling when necessary.

Laravel使用DB façade执行数据库操作不会触发Eloquent ORM模型事件

使用DB façade执行数据库操作不会触发saving、saved等Eloquent ORM模型事件。当我们不想在事件监听器或队列任务中触发Eloquent ORM模型事件时,除了使用Eloquent ORM模型的saveQuietly、deleteQuietly等方法之外,还可以直接使用DB façade执行数据库操作。

在Eloquent ORM模型事件监听器和队列任务中,要避免使用Eloquent模型增删改查方法,例如create、update、save等。否则会陷入调用死循环 —— 模型事件监听器分发队列任务,队列任务触发模型事件,模型事件监听器再次分发队列任务,队列任务再次触发模型事件……死循环了。

Modify and Persist Model Instances in Laravel Using the saved Event, Not the saving Event

In Laravel, don’t call the save method on a model instance inside the saving event listener.

If you need to modify a model’s field and persist it within a model event listener, make sure you’re using the saved event, not the saving event. This is particularly important when your event listeners are queued for asynchronous execution.

The saving event occurs before the model is persisted to the database. If you try to modify a field and call save() within this listener, it won’t actually persist to the database, especially when the listener is queued for async execution. For example, modifying the slug field might not actually update in the database.

Instead, use the saved event listener and call saveQuietly to persist the changes, as shown in the example:

static::saved(queueable(function (Topic $topic) {
    // If the slug is empty, translate the title into a slug
    if (!$topic->slug) {
        $topic->slug = app(SlugTranslateHandler::class)->translate($topic->title);
        $topic->saveQuietly();
    }
}));

By using the saved event and saveQuietly, you ensure that your changes are made after the model is successfully persisted, avoiding any issues with asynchronous queue execution.

Laravel框架应该在saved而不是saving事件监听器中修改模型实例并持久化

不要在saving事件的监听器中运行模型实例的save方法。

要在模型事件的闭包监听器中修改模型实例的某个字段的值并持久化,当模型事件的闭包监听器作为队列任务异步执行时,不能监听saving事件,因为该事件表示模型实例还未持久化到数据库里,因此监听器作为队列任务异步执行的话,就会导致模型实例的某个字段(例如下例的slug字段)的值不能真正持久化到数据库里(记住,不应该在saving事件的监听器里调用模型实例的save方法)。应该在saved事件监听器里saveQuietly模型实例,例如:

static::saved(queueable(function (Topic $topic) {
    // 如果slug字段无内容,就使用翻译器对title字段进行翻译
    if (!$topic->slug) {
        $topic->slug = app(SlugTranslateHandler::class)->translate($topic->title);
        $topic->saveQuietly();
    }
}));

When Clients Don’t Need to Initialize CSRF Tokens in Laravel

In Laravel, clients don’t need to initialize CSRF tokens under the following conditions:

  • Cookie and Session-based Authentication: When using cookie and session-based user authentication, and the route being accessed is part of web.php with the App\Http\Middleware\VerifyCsrfToken middleware enabled, CSRF tokens are required.

Authorization Points in the Laravel Framework (Where Authorization Takes Place)

In the Laravel framework, authorization can be implemented in the following places:

  • Using the can Middleware: This middleware allows for permission checks at the route level, providing an easy way to ensure that the user has the required authorization.
  • Using the authorize Method in Form Request Validation Classes: The authorize method is used to determine whether the user is authorized to make a given request. Note that if you generate a form request validation class using the php artisan command, it will come with a default return false in the authorize method.
  • Using authorize, can, or cannot Methods in Controller Actions: Within controller methods, you can use these methods to check if the user has the required permissions before performing an action.
  • Using @can and @cannot Directives in Blade Templates: These Blade directives allow you to conditionally display content based on whether the user has a specific ability or permission.
  • Using Sanctum Token Abilities: When using Sanctum for API authentication, you can define and check token abilities to manage access at a granular level.

Laravel框架的鉴权点(在框架的哪些地方鉴权)

可以在Laravel框架的以下地方鉴权:

  • 使用can中间件
  • 使用表单请求数据验证类的authorize方法。注意,使用php artisan命令创建的表单请求数据验证类,默认包含return false的authorize方法
  • 在控制器的方法里使用authorize、can、cannot等方法
  • 在Blade模板中使用@can、@cannot等指令
  • 使用Sanctum的令牌能力

没有必要使用laravel-debugbar调试工具了

在Laravel 5.7版本中,Telescope被官方引入并且作为官方推荐包提供。在Laravel 5.7版本之前,除了可以使用社区维护的Telescope之外,还可以使用Laravel开发者工具laravel-debugbar包。

现在Laravel最新版本是11,Telescope的调试功能已经比laravel-debugbar强大了,因此没有必要使用laravel-debugbar作为调试工具了。

新版本的Laravel没有必要使用Laravel Scaffold Generator作为代码生成器了

Laravel 5.3+ Scaffold Generator代码生成器能让你通过执行一条 Artisan 命令,完成注册路由、新建模型、新建表单验证类、新建资源控制器以及所需视图文件等任务,不仅约束了项目开发的风格,还能极大地提高我们的开发效率。

但是Laravel 10、11 等高版本,在使用 php artisan make:model 命令生成模型类的文件时,可以开启–all 或 -a 选项,来同时生成对应的迁移、工厂、填充器、策略、控制器和表单请求等文件:

php artisan make:model Flight –all
php artisan make:model Flight -a

所以,已经无需使用Laravel Scaffold Generator作为代码生成器了!