搜尋
首頁php框架Laravel快速入門Laravel模型事件

快速入門Laravel模型事件

May 01, 2020 pm 01:07 PM
laravel

Laravel 模型事件讓你監聽模型生命週期內的多個關鍵點,甚至可以在阻止一個模型的保存或刪除。 Laravel 模型事件文件 概述如何使用鉤子將對應事件與相關的事件類型關聯起來,但是本文的主旨是事件與監聽器的構建與設置,並額外補充一些細節的說明。

事件概述

Eloquent 有很多事件可以讓你使用鉤子將它們關聯起來,並且增加自訂的功能到你的模型中。此模型起始時有以下事件:

retrieved

creating

#created

updating

updated

# saving

saved

deleting

deleted

restoring

restored

從文件這裡我們可以了解它們都是如何實現的,你還可以進入Model 的基底類別去看看它們到底是如何實現的:

當現有模型被資料庫檢索時, retrieved 事件將會觸發。當一個新的模型被第一次儲存時, creating 和 created 事件將會觸發。如果對一個已經存在於資料庫的模型呼叫 save 方法, updating / updated 事件將會觸發。無論怎樣,在這兩種情況下, saving / saved 事件都會觸發。

文件中對模型事件進行了很好的概述,同時解釋瞭怎樣使用鉤子去關聯事件,但是如果你是初學者,或者並不是熟悉怎樣使用鉤子將事件監聽器與這些自定義模型事件相關聯,請進一步閱讀本文。

註冊事件

為了在你的模型中關聯一個事件,你需要做的第一件事是使用$dispatchesEvents 屬性去註冊事件對象,這最終將透過  HasEvents::fireCustomModelEvent() 方法觸發,該方法將透過  fireModelEvent() 方法被呼叫。 fireCustomModelEvent() 方法原始的時候大致是下面這樣:

/**
 * 为给定的事件触发一个自定义模型。
 *
 * @param  string  $event
 * @param  string  $method
 * @return mixed|null
 */
protected function fireCustomModelEvent($event, $method)
{
    if (! isset($this->dispatchesEvents[$event])) {
        return;
    }
    $result = static::$dispatcher->$method(new $this->dispatchesEvents[$event]($this));
    if (! is_null($result)) {
        return $result;
    }
}

一些事件,例如 delete, 將進行檢測判斷是否這個事件會回傳 false 然後退出操作。例如,你可以使用這個鉤子去做一些檢測,也可以防止一個使用者被建立或刪除。

使用  App\User 模型舉例,這裡展示瞭如何配置你的模型事件:

protected $dispatchesEvents = [
    'saving' => \App\Events\UserSaving::class,
];

你可以使用artisan make:event 命令來為你創建這個事件,但基本上這將是你最後得到結果:

<?php
namespace App\Events;
use App\User;
use Illuminate\Queue\SerializesModels;
class UserSaving
{
    use SerializesModels;
    public $user;
    /**
     *  创建一个新的事件实例
     *
     * @param \App\User $user
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

我們的事件提供了一個公有的$user 屬性以便你能夠在saving 事件期間存取User 模型實例。

為了讓它運作起來下一步需要做的是為這個事件建立一個實際的監聽器。我們設定好模型的觸發時機,當 User 模型觸發 saving 事件,監聽器就會被調。

建立一個事件監聽器

現在,我們定義 User 模型並註冊一個事件監聽器來監聽 saving 事件的觸發。雖然,我可以透過模型觀察器快速實現,但是,我想引導你為單一事件觸發配置事件監聽器。

事件監聽器就像 Laravel 其它事件監聽一樣,handle() 方法將會接收 App\Events\UserSaving 事件類別的一個實例。

你可以手動建立它,也可以使用 php artisan make:listener 指令。不管怎麼樣,你都會創建一個像下面這樣子監聽類別:

<?php
namespace App\Listeners;
use App\Events\UserSaving as UserSavingEvent;
class UserSaving
{
    /**
     * 处理事件。
     *
     * @param  \App\Events\UserSavingEvent $event
     * @return mixed
     */
    public function handle(UserSavingEvent $event)
    {
        app(&#39;log&#39;)->info($event->user);
    }
}

我只是添加了一個日誌記錄調用,以便於檢查傳遞給監聽器的模型。為此,我們還需要在 EventServiceProvider::$listen 屬性中註冊監聽器:

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
    /**
     * 应用的事件监听器。
     * 
     * @var array
     */
    protected $listen = [
        \App\Events\UserSaving::class => [
            \App\Listeners\UserSaving::class,
        ],
    ];
    // ...
}

現在,當模型呼叫 saving 事件時,我們註冊的事件監聽器也會被觸發並執行。

嘗試事件監聽

我們可以透過tinker 會話快速產生事件監聽程式碼:

php artisan tinker
>>> factory(\App\User::class)->create();
=> App\User {#794
     name: "Aiden Cremin",
     email: "josie05@example.com",
     updated_at: "2018-03-15 03:57:18",
     created_at: "2018-03-15 03:57:18",
     id: 2,
   }

如果你已正確註冊了事件和監聽器,則應該在  laravel.log 檔案中可以看到該模型的JSON 表達式形式:

[2018-03-15 03:57:18] local.INFO: {"name":"Aiden Cremin","email":"josie05@example.com"}

要注意的一點,此時模型並沒有created_at 或updated_at 屬性。如果在模型上再次呼叫save() ,日誌上將會有一個帶有時間戳記的新記錄,因為saving 事件會在新建立的記錄或現在有記錄上觸發:

>>> $u = factory(\App\User::class)->create();
=> App\User {#741
     name: "Eloisa Hirthe",
     email: "gottlieb.itzel@example.com",
     updated_at: "2018-03-15 03:59:37",
     created_at: "2018-03-15 03:59:37",
     id: 3,
   }
>>> $u->save();
=> true
>>>

停止一個儲存操作

某些模型事件是允許你進行阻止操作的。舉個荒謬的例子,假設我們不允許任何一個使用者的模型保存其屬性$user->name  的內容為Paul :

/**
 * 处理事件。
 *
 * @param  \App\Events\UserSaving $event
 * @return mixed
 */
public function handle(UserSaving $event)
{
    if (stripos($event->user->name, &#39;paul&#39;) !== false) {
        return false;
    }
}

在Eloquent 的Model::save() 方法中,會根據事件監聽的回傳結果判斷是否進行停止儲存作業:

public function save(array $options = [])
{
    $query = $this->newQueryWithoutScopes();
    // 如果 "saving" 事件返回 false ,我们将退出保存并返回
    // false,表示保存失败。这为服务监听者提供了一个机会,
    // 当验证失败或者出现其它任何情况,都可以取消保存操作。
    if ($this->fireModelEvent(&#39;saving&#39;) === false) {
        return false;
    }

這個  save()  是個很好的例子,它告訴了你如何在模型生命週期中自訂事件,以及被動執行日誌資料記錄或任務調度。

使用觀察者

如果你正在監聽多個事件,那麼你可能會發現使用觀察者類別來按類型分組存放事件會更加方便。這裡是一個範例  Eloquent 觀察者 :

<?php
namespace App\Observers;
use App\User;
class UserObserver
{
    /**
     * 监听 User 创建事件。
     *
     * @param  \App\User  $user
     * @return void
     */
    public function created(User $user)
    {
        //
    }
    /**
     * 监听 User 删除事件。
     *
     * @param  \App\User  $user
     * @return void
     */
    public function deleting(User $user)
    {
        //
    }
}

你可以在服務提供者 AppServiceProvider 中的 boot() 方法裡註冊觀察者。

/**
 * 运行所有应用服务。
 *
 * @return void
 */
public function boot()
{
    User::observe(UserObserver::class);
}

推荐教程:《Laravel教程

以上是快速入門Laravel模型事件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
Laravel的影響:簡化網絡開發Laravel的影響:簡化網絡開發Apr 21, 2025 am 12:18 AM

Laravel通過簡化Web開發過程和提供強大功能脫穎而出。其優勢包括:1)簡潔的語法和強大的ORM系統,2)高效的路由和認證系統,3)豐富的第三方庫支持,使得開發者能專注於編寫優雅的代碼並提高開發效率。

Laravel:前端還是後端?澄清框架的角色Laravel:前端還是後端?澄清框架的角色Apr 21, 2025 am 12:17 AM

laravelispredminandermanthandermanthandermanthandermanthermanderframework,設計Forserver-SideLogic,databasemagement,andapideplupment,thryitalsosupportsfortfortsfrontenddevelopmentwithbladeTemplates。

Laravel vs. Python:探索性能和可擴展性Laravel vs. Python:探索性能和可擴展性Apr 21, 2025 am 12:16 AM

Laravel和Python在性能和可擴展性方面的表現各有優劣。 Laravel通過異步處理和隊列系統提升性能,但受PHP限制在高並發時可能有瓶頸;Python利用異步框架和強大的庫生態系統表現出色,但在多線程環境下受GIL影響。

Laravel vs. Python(與框架):比較分析Laravel vs. Python(與框架):比較分析Apr 21, 2025 am 12:15 AM

Laravel適合團隊熟悉PHP且需功能豐富的項目,Python框架則視項目需求而定。 1.Laravel提供優雅語法和豐富功能,適合需要快速開發和靈活性的項目。 2.Django適合複雜應用,因其“電池包含”理念。 3.Flask適用於快速原型和小型項目,提供極大靈活性。

Laravel的前端:探索可能性Laravel的前端:探索可能性Apr 20, 2025 am 12:19 AM

Laravel可以用於前端開發。 1)使用Blade模板引擎生成HTML。 2)集成Vite管理前端資源。 3)構建SPA、PWA或靜態網站。 4)結合路由、中間件和EloquentORM創建完整Web應用。

PHP和Laravel:構建服務器端應用程序PHP和Laravel:構建服務器端應用程序Apr 20, 2025 am 12:17 AM

PHP和Laravel可用於構建高效的服務器端應用。 1.PHP是開源腳本語言,適用於Web開發。 2.Laravel提供路由、控制器、EloquentORM、Blade模板引擎等功能,簡化開發。 3.通過緩存、代碼優化和安全措施,提升應用性能和安全性。 4.測試和部署策略確保應用穩定運行。

Laravel vs. Python:學習曲線和易用性Laravel vs. Python:學習曲線和易用性Apr 20, 2025 am 12:17 AM

Laravel和Python在學習曲線和易用性上的表現各有優劣。 Laravel適合快速開發Web應用,學習曲線相對平緩,但掌握高級功能需時間;Python語法簡潔,學習曲線平緩,但動態類型系統需謹慎。

Laravel的優勢:後端發展Laravel的優勢:後端發展Apr 20, 2025 am 12:16 AM

Laravel在後端開發中的優勢包括:1)優雅的語法和EloquentORM簡化了開發流程;2)豐富的生態系統和活躍的社區支持;3)提高了開發效率和代碼質量。 Laravel的設計讓開發者能夠更高效地進行開發,並通過其強大的功能和工具提升代碼質量。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用