<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在 Laravel 的世界中,你對 Eloquent 大多數操作都會或多或少的觸發一些模型事件,今天就來看一下模型事件的使用。 Laravel 事先已經定義好了 10 個模型事件以供我們使用,它們分別是: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored。 事件名稱都很淺顯易懂,如果你是認真寫代碼話都應該可以看明白,如果不明白的話可以左轉百度。 不過你可能對 updating, updated, saving, saved 這四個事件有所疑惑,所以我們來詳細分析一下。 打開 Illuminate\Database\Eloquent\Model ,找到位于 517 行的 save 方法 筆者使用的是 Laravel 5.5 最新版本,如果你使用的是其他版本,請自行在官方文檔 版本差異 中對比你的版本 ~~~ public function save(array $options = []) { $query = $this->newQueryWithoutScopes(); if ($this->fireModelEvent('saving') === false) { return false; } if ($this->exists) { $saved = $this->isDirty() ? $this->performUpdate($query) : true; } else { $saved = $this->performInsert($query); if (! $this->getConnectionName() && $connection = $query->getConnection()) { $this->setConnection($connection->getName()); } } if ($saved) { $this->finishSave($options); } return $saved; } ~~~ 可以看到首先觸發的是 saving: ~~~ $this->fireModelEvent('saving') ~~~ 接著會判斷此 model 是不是新創建的。 如果是新創建的,那么則會進行 insert 操作,由于本例是分析修改操作,所以這里直接略過。 如果不是新創建的,那么會調用 isDirty 方法判斷此 model 是否進行了修改。 如果進行了修改,那么會調用 performUpdate 方法進行更新操作,如果沒有進行修改,則直接返回 true。 讓我們點開 performUpdate 方法。 ~~~ protected function performUpdate(Builder $query) { if ($this->fireModelEvent('updating') === false) { return false; } if ($this->usesTimestamps()) { $this->updateTimestamps(); } $dirty = $this->getDirty(); if (count($dirty) > 0) { $this->setKeysForSaveQuery($query)->update($dirty); $this->fireModelEvent('updated', false); $this->syncChanges(); } return true; } ~~~ 可以看到這里會觸發 updating: ~~~ $this->fireModelEvent('updating') ~~~ 如果返回的不是 false ,那么會接著往下走,判斷一下此模型是否使用了 Timestamp,如果使用了,那么則先更新自身的 Timestamp: ~~~ if ($this->usesTimestamps()) { $this->updateTimestamps(); } ~~~ 接著調用 getDirty,顧名思義,大概可以知道這個方法是獲取自身的臟值,讓我們點開看一下: ~~~ public function getDirty() { $dirty = []; foreach ($this->getAttributes() as $key => $value) { if (! $this->originalIsEquivalent($key, $value)) { $dirty[$key] = $value; } } return $dirty; } ~~~ 意料之中,此方法內會返回自身被修改后的臟值,如果你打印過 Laravel 的 Model 實例,那么相信你會看到實例中有 original 和 attributes 兩個數組。 其中 original 保存的是最初始的實例屬性,無法被外部直接修改。 attributes 數組則是可以被自有修改,此方法即是由判斷兩個數組的差異而返回臟值,由于時間原因,這里不做過多詳解,有機會單開一個文章慢慢講。 繼續往下走,可以看到這里會判斷一下是否有臟值: ~~~ if (count($dirty) > 0) ~~~ 只有在存在臟值的情況下才會進入 if 內部,執行 update 操作,繼而觸發 updated 事件 在 update 結束后會執行一下 syncChanges 同步一下自身的數據 OK, performUpdate 方法解析完畢,讓我們回到 save 方法,接著往下看,可以看到 Laravel 最后做了一個判斷: ~~~ if ($saved) { $this->finishSave($options); } ~~~ 只有在 update 成功的情況下,才會觸發 finishSave() 方法,此方法會接收一個參數 $options,即是修改的屬性。 讓我們點開此方法: ~~~ protected function finishSave(array $options) { $this->fireModelEvent('saved', false); if ($this->isDirty() && ($options['touch'] ?? true)) { $this->touchOwners(); } $this->syncOriginal(); } ~~~ 可以看到在此方法內會觸發 saved 事件 分析完畢,大概可以做一個總結了。 當模型已存在,不是新建的時候,依次觸發的順序是: saving -> updating -> updated -> saved 當模型不存在,需要新增的時候,依次觸發的順序則是 saving -> creating -> created -> saved 那么 saving,saved 和 updating,updated 到底有什么區別呢? 上面已經講過,Laravel 的 Eloquent 會維護實例的兩個數組,分別是 original 和 attributes。 只有在 saved 事件觸發之后,Laravel 才會對兩個數組執行 syncOriginal 操作,這樣就很好理解了。 updating 和 updated 會在數據庫中的真值修改前后觸發。 saving 和 saved 則會在 Eloquent 實例的 original 數組真值更改前后觸發。 這樣我們就可以根據業務場景來選擇更合適的觸發事件了~ **Observer (觀察者)** 如果你想在一個模型中監聽多個事件,那么你可以把它寫成一個類,類中的方法名稱即是你想要監聽的事件名稱 ~~~ class UserObserver { /** * 監聽數據即將創建的事件。 * * @param User $user * @return void */ public function creating(User $user) { } /** * 監聽數據創建后的事件。 * * @param User $user * @return void */ public function created(User $user) { } /** * 監聽數據即將更新的事件。 * * @param User $user * @return void */ public function updating(User $user) { } /** * 監聽數據更新后的事件。 * * @param User $user * @return void */ public function updated(User $user) { } /** * 監聽數據即將保存的事件。 * * @param User $user * @return void */ public function saving(User $user) { } /** * 監聽數據保存后的事件。 * * @param User $user * @return void */ public function saved(User $user) { } /** * 監聽數據即將刪除的事件。 * * @param User $user * @return void */ public function deleting(User $user) { } /** * 監聽數據刪除后的事件。 * * @param User $user * @return void */ public function deleted(User $user) { } /** * 監聽數據即將從軟刪除狀態恢復的事件。 * * @param User $user * @return void */ public function restoring(User $user) { } /** * 監聽數據從軟刪除狀態恢復后的事件。 * * @param User $user * @return void */ public function restored(User $user) { } } ~~~ 然后在 AppServiceProvider 中注冊此觀察者 ~~~ <?php namespace App\Providers; use App\User; use App\Observers\UserObserver; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * 運行所有應用. * * @return void */ public function boot() { // 為 User 模型注冊觀察者 User::observe(UserObserver::class); } /** * 注冊服務提供. * * @return void */ public function register() { // } } ~~~ 然后你就可以在你注冊的 Observer 中觀測到各種事件啦~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看