快速入門
快速入門
Eloquent:入門
簡介
Laravel 的 Eloquent ORM 提供了一個漂亮、簡潔的 ActiveRecord 實現來和數據庫交互。每個數據庫表都有一個對應的「模型」用來與該表交互。你可以通過模型查詢數據表中的數據,以及在數據表中插入新記錄。
在開始之前,請確保在 config/database.php
中配置數據庫連接。更多關于數據庫配置的信息,請查看 文檔。
模型定義
首先,創(chuàng)建一個 Eloquent 模型。 模型通常在 app
目錄中,但你可以根據 composer.json
文件將他們放置在可以被自動加載的任意位置。所有的 Eloquent 模型都繼承至 Illuminate\Database\Eloquent\Model
類。
創(chuàng)建模型最簡單的方法就是使用 make:model
Artisan 命令:
php artisan make:model Flight
如果要在生成模型的時候生成 數據庫遷移 ,可以使用 --migration
或 -m
選項:
php artisan make:model Flight --migration php artisan make:model Flight -m
Eloquent 模型約定
現在,我們來看一個 Flight
模型的示例,我們將用它從 flights
數據庫表中檢索和存儲數據信息:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ // }
數據表名稱
請注意,我們并沒有告訴 Eloquent 我們的 Flight
模型使用哪個數據表。 除非明確地指定了其它名稱,否則將使用類的復數形式「蛇形命名」來作為表名。因此,在這種情況下,Eloquent 將假設 Flight
模型存儲的是 flights
數據表中的數據。你可以通過在模型上定義 table
屬性來指定自定義數據表:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 與模型關聯的表名 * * @var string */ protected $table = 'my_flights'; }
主鍵
Eloquent 也會假設每個數據表都有一個名為 id
的主鍵列。你可以定義一個受保護的 $primaryKey
屬性來重寫約定。
此外,Eloquent 假設主鍵是一個自增的整數值,這意味著默認情況下主鍵會自動轉換為 int
類型。如果您希望使用非遞增或非數字的主鍵則需要設置公共的 $incrementing
屬性設置為 false
。如果你的主鍵不是一個整數,你需要將模型上受保護的 $keyType
屬性設置為 string
。
時間戳
默認情況下,Eloquent 預期你的數據表中存在 created_at
和 updated_at
。如果你不想讓 Eloquent 自動管理這兩個列, 請將模型中的 $timestamps
屬性設置為 false
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 指示模型是否自動維護時間戳 * * @var bool */ public $timestamps = false; }
如果需要自定義時間戳的格式,在你的模型中設置 $dateFormat
屬性。這個屬性決定日期屬性在數據庫的存儲方式,以及模型序列化為數組或者 JSON 的格式:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型日期列的存儲格式。 * * @var string */ protected $dateFormat = 'U'; }
如果你需要自定義存儲時間戳的字段名,可以在模型中設置 CREATED_AT
和 UPDATED_AT
常量的值來實現:
<?php class Flight extends Model{ const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update'; }
數據庫連接
默認情況下,Eloquent 模型將使用你的應用程序配置的默認數據庫連接。如果你想為模型指定一個不同的連接,設置 $connection
屬性:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型的連接名稱 * * @var string */ protected $connection = 'connection-name'; }
默認屬性值
如果要為模型的某些屬性定義默認值,可以在模型上定義 $attributes
屬性:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型的默認屬性值。 * * @var array */ protected $attributes = [ 'delayed' => false, ]; }
模型檢索
創(chuàng)建模型和 它關聯的數據庫表后,你就可以從數據庫中查詢數據了。將每個 Eloquent 模型想象成一個強大的查詢構造器 query builder ,你可以用它更快速的查詢與其相關聯的數據表。例如:
<?php $flights = App\Flight::all(); foreach ($flights as $flight) { echo $flight->name; }
附加約束
Eloquent 的 all
方法會返回模型中所有的結果。由于每個 Eloquent 模型都充當一個查詢構造器,所以你也可以添加查詢條件,然后使用 get
方法獲取查詢結果:
$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();
{tip} 因為 Eloquent 模型也是查詢構造器,所以你也應當閱讀 查詢構造器可用的所有方法。你可以在 Eloquent 查詢中使用這些方法。
重新加載模型
你可以使用 fresh
和 refresh
方法重新加載模型。 fresh
方法會重新從數據庫中檢索模型?,F有的模型實例不受影響:
$flight = App\Flight::where('number', 'FR 900')->first(); $freshFlight = $flight->fresh();
refresh
方法使用數據庫中的新數據重新賦值現有模型。此外,已經加載的關系會被重新加載:
$flight = App\Flight::where('number', 'FR 900')->first(); $flight->number = 'FR 456';$flight->refresh(); $flight->number; // "FR 900"
集合
對于 Eloquent 中的 all
和 get
方法可以查詢多個結果,返回一個 Illuminate\Database\Eloquent\Collection
實例。 Collection
類提供了 很多輔助函數 來處理 Eloquent 結果:
$flights = $flights->reject(function ($flight) { return $flight->cancelled; });
你可以像數組一樣遍歷集合:
foreach ($flights as $flight) { echo $flight->name; }
分塊結果
如果你需要處理數以千計的 Eloquent 結果,使用 chunk
命令。 chunk
方法會檢索 Eloquent 模型中的『分塊』將他們提供給指定的 Closure
處理。在處理大型結果集時,使用 chunk
方法可以節(jié)省內存:
Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // } });
傳遞到方法的第一個參數是希望每個『分塊』接收的數據量。閉包作為第二個參數傳遞,它在每次從數據庫中檢索分塊的時候調用。它將執(zhí)行數據庫查詢把檢索分塊的結果傳遞給閉包方法。
使用游標
cursor
方法允許你使用游標遍歷數據庫,它只執(zhí)行一次查詢。處理大量的數據時, cursor
方法可以大大減少內存的使用量:
foreach (Flight::where('foo', 'bar')->cursor() as $flight) { // }
檢索單個模型 / 集合
除了從指定的數據表檢索所有記錄外,你可以使用 find
或 first
方法來檢索單條記錄。這些方法返回單個模型實例,而不是返回模型集合:
// 通過主鍵檢索一個模型... $flight = App\Flight::find(1); // 檢索符合查詢限制的第一個模型... $flight = App\Flight::where('active', 1)->first();
你也可以使用主鍵數組作為參數調用 find
方法,它將返回匹配記錄的集合:
$flights = App\Flight::find([1, 2, 3]);
『未找到』異常
有時你希望在未找到模型時拋出異常。這在控制器和路由中非常有用。 findOrFail
和 firstOrFail
方法會檢索查詢的第一個結果,如果未找到,將拋出 Illuminate\Database\Eloquent\ModelNotFoundException
異常:
$model = App\Flight::findOrFail(1); $model = App\Flight::where('legs', '>', 100)->firstOrFail();
如果沒有捕獲異常,則會自動返回 404
響應給用戶。也就是說,使用這些方法時,沒有必要再寫個檢查來返回 404
響應::
Route::get('/api/flights/{id}', function ($id) { return App\Flight::findOrFail($id); });
檢索集合
你還可以使用 查詢構造器 提供的 count
, sum
, max
, 和其他的聚合函數。這些方法只會返回適當的標量值而不是一個模型實例:
$count = App\Flight::where('active', 1)->count(); $max = App\Flight::where('active', 1)->max('price');
插入 & 更新模型
插入
要往數據庫新增一條記錄,先創(chuàng)建新模型實例,給實例設置屬性,然后調用 save
方法:
<?php namespace App\Http\Controllers; use App\Flight;use Illuminate\Http\Request; use App\Http\Controllers\Controller; class FlightController extends Controller{ /** * 創(chuàng)建一個新的航班實例 * * @param Request $request * @return Response */ public function store(Request $request) { // 校驗請求... $flight = new Flight; $flight->name = $request->name; $flight->save(); } }
在這個示例中,我們將 HTTP 請求參數 name
賦值給了 App\Flight
模型實例的 name
屬性。當調用 save
方法時,將會插入一條新記錄。 created_at
和 updated_at
時間戳將會自動設置,不需要手動賦值。
更新
save
方法也可以用來更新數據庫已經存在的模型。更新模型,你需要先檢索出來,設置要更新的屬性,然后調用 save
方法。同樣, updated_at
時間戳會自動更新,所以也不需要手動賦值:
$flight = App\Flight::find(1); $flight->name = 'New Flight Name';$flight->save();
批量更新
也可以更新匹配查詢條件的多個模型。在這個示例中,所有的 active
和 destination
為 San Diego
的航班會標記為延誤:
App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);
update
方法接受一個鍵為字段名稱數據為值的數組。
{note} 通過 Eloquent 批量更新時, 更新的模型不會觸發(fā)
saved
和updated
事件。因為在批量更新時,從不會去檢索模型。
批量賦值
你也可以使用 create
方法來保存新模型,此方法會返回模型實例。不過,在使用之前,你需要在模型上指定 fillable
或 guarded
屬性,因為所有的 Eloquent 模型都默認不可進行批量賦值。
當用戶通過 HTTP 請求傳入一個意外的參數,并且該參數更改了數據庫中你不需要更改的字段時。比如:惡意用戶可能會通過 HTTP 請求傳入 is_admin
參數,然后將其傳給 create
方法,此操作能讓用戶將自己升級成管理員。
所以,在開始之前,你應該定義好模型上的哪些屬性是可以被批量賦值的。你可以通過模型上的 $fillable
屬性來實現。 例如:讓 Flight
模型的 name
屬性可以被批量賦值:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 可以被批量賦值的屬性。 * * @var array */ protected $fillable = ['name']; }
一旦我們設置好了可以批量賦值的屬性,就可以通過 create
方法插入新數據到數據庫中了。 create
方法將返回保存的模型實例:
$flight = App\Flight::create(['name' => 'Flight 10']);
如果你已經有一個模型實例,你可以傳遞一個數組給 fill
方法來賦值:
$flight->fill(['name' => 'Flight 22']);
保護屬性
$fillable
可以看作批量賦值的「白名單」, 你也可以使用 $guarded
屬性來實現。 $guarded
屬性包含的是不允許批量賦值的數組。也就是說, $guarded
從功能上將更像是一個「黑名單」。注意:你只能使用 $fillable
或 $guarded
二者中的一個,不可同時使用。下面這個例子中,除了 price
屬性,其他的屬性都可以批量賦值:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 不可批量賦值的屬性。 * * @var array */ protected $guarded = ['price']; }
如果你想讓所有屬性都可以批量賦值, 你可以將 $guarded
定義成一個空數組:
/** * 不可以批量賦值的屬性。 * * @var array */ protected $guarded = [];
其他創(chuàng)建方法
firstOrCreate
/ firstOrNew
這里有兩個你可能用來批量賦值的方法: firstOrCreate
和 firstOrNew
。firstOrCreate
方法會通過給定的 列 / 值 來匹配數據庫中的數據。如果在數據庫中找不到對應的模型, 則會從第一個參數的屬性乃至第二個參數的屬性中創(chuàng)建一條記錄插入到數據庫。
firstOrNew
方法像 firstOrCreate
方法一樣嘗試通過給定的屬性查找數據庫中的記錄。不同的是,如果 firstOrNew
方法找不到對應的模型,會返回一個新的模型實例。注意 firstOrNew
返回的模型實例尚未保存到數據庫中,你需要手動調用 save
方法來保存:
// 通過 name 來查找航班,不存在則創(chuàng)建... $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); // 通過 name 查找航班,不存在則使用 name 和 delayed 屬性創(chuàng)建... $flight = App\Flight::firstOrCreate(['name' => 'Flight 10'], ['delayed' => 1]); // 通過 name 查找航班,不存在則創(chuàng)建一個實例... $flight = App\Flight::firstOrNew(['name' => 'Flight 10']); // 通過 name 查找航班,不存在則使用 name 和 delayed 屬性創(chuàng)建一個實例... $flight = App\Flight::firstOrNew(['name' => 'Flight 10'], ['delayed' => 1]);
updateOrCreate
你還可能遇到希望更新現有模型或在不存在的情況下則創(chuàng)建新的模型的情景。 Laravel 提供了 updateOrCreate
方法僅一個步驟就可以實現。跟 firstOrCreate
方法一樣,updateOrCreate
匹配到對應模型,所以不需要調用 save()
方法:
// 如果有從奧克蘭到圣地亞哥的航班,則價格定為99美元。 // 如果沒匹配到存在的模型,則創(chuàng)建一個。 $flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );
刪除模型
可以在模型實例上調用 delete
方法來刪除實例:
$flight = App\Flight::find(1); $flight->delete();
通過主鍵刪除模型
在上面的例子中,在調用 delete
之前需要先去數據庫中查找對應的模型。事實上,如果你知道了模型的主鍵,你可以直接使用 destroy
方法來刪除模型,而不用先去數據庫中查找。 destroy
方法除了接受單個主鍵作為參數之外,還接受多個主鍵,或者使用數組,集合來保存多個主鍵:
App\Flight::destroy(1); App\Flight::destroy(1, 2, 3); App\Flight::destroy([1, 2, 3]); App\Flight::destroy(collect([1, 2, 3]));
通過查詢刪除模型
你也可以在模型上運行刪除語句。在這個例子中,我們將刪除所有標記為非活躍的航班。與批量更新一樣,批量刪除不會為刪除的模型啟動任何模型事件:
$deletedRows = App\Flight::where('active', 0)->delete();
{note} 通過 Eloquent 執(zhí)行批量刪除語句時,不會觸發(fā)
deleting
和deleted
模型事件。因此,在執(zhí)行刪除語句時,從不檢索模型示例。
軟刪除
除了真實刪除數據庫記錄, Eloquent 也可以「軟刪除」模型。軟刪除的模型并不是真的從數據庫中刪除了。事實上,是在模型上設置了 deleted_at
屬性并將其值寫入數據庫。如果 deleted_at
值非空,代表這個模型已被軟刪除。如果要開啟模型軟刪除功能,你需要在模型上使用 Illuminate\Database\Eloquent\SoftDeletes
trait:
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Flight extends Model{ use SoftDeletes; }
{tip}
SoftDeletes
trait 會自動將deleted_at
屬性轉換成DateTime
/Carbon
實例
當然,你需要把 deleted_at
字段添加到數據表中。 Laravel 的 數據庫遷移 有創(chuàng)建這個字段的方法:
Schema::table('flights', function (Blueprint $table) { $table->softDeletes(); });
那現在,當你在模型實例上使用 delete
方法, 當前日期時間會寫入 deleted_at
字段。同時,查詢出來的結果也會自動排除已被軟刪除的記錄。
你可以使用 trashed
方法來驗證當前模型是否軟刪除:
if ($flight->trashed()) { // }
查詢軟刪除模型
包括已軟刪除的模型
前面提到,查詢結果會自動剔除已被軟刪除的結果。當然,你可以使用 withTrashed
方法來獲取包括軟刪除模型在內的模型:
$flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();
withTrashed
方法也可以用在 關聯 查詢:
$flight->history()->withTrashed()->get();
檢索軟刪除模型
onlyTrashed
方法 只 獲取已軟刪除的模型:
$flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();
恢復軟刪除模型
有時會對軟刪除模型進行 「撤銷」,在已軟刪除的數據上使用 restore
方法即可恢復到有效狀態(tài):
$flight->restore();
你也可以在查詢中使用 restore
方法,從而快速恢復多個模型。和其他批量」操作一樣,這個操作不會觸發(fā)模型的任何事件:
App\Flight::withTrashed() ->where('airline_id', 1) ->restore();
類似 withTrashed
方法, restore
方法也用在 關聯上:
$flight->history()->restore();
永久刪除
要真實刪除數據時,使用 forceDelete
方法即可:
// 單個模型實例的永久刪除... $flight->forceDelete(); // 關聯模型的永久刪除... $flight->history()->forceDelete();
查詢作用域
全局作用域
全局作用域可以給模型的查詢都添加上約束。Laravel 的 軟刪除 功能就是利用此特性從數據庫中獲取 「未刪除」的模型。 你可以編寫你自己的全局作用域,很簡單、方便的為每個模型查詢都加上約束條件:
編寫全局作用域
編寫全局作用域很簡單。定義一個實現 Illuminate\Database\Eloquent\Scope
接口的類,并實現 apply
這個方法。 根據你的需求,在 apply
方法中加入查詢的 where
條件:
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class AgeScope implements Scope{ /** * 把約束加到 Eloquent 查詢構造中。 * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { $builder->where('age', '>', 200); } }
{tip} 如果需要在 select 語句里添加字段,應使用
addSelect
方法,而不是select
方法。 這將有效防止無意中替換現有 select 語句的情況。
應用全局作用域
要將全局作用域分配給模型,需要重寫模型的 boot
方法并使用 addGlobalScope
方法:
<?php namespace App;use App\Scopes\AgeScope; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 模型的 「啟動」 方法. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope(new AgeScope); } }
添加作用域后,對 User::all()
的查詢會生成以下 SQL 查詢語句:
select * from `users` where `age` > 200
匿名全局作用域
Eloquent 同樣允許使用閉包定義全局作用域,這樣就不需要為一個簡單的作用域而編寫一個單獨的類:
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class User extends Model{ /** *模型的「啟動」方法. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope('age', function (Builder $builder) { $builder->where('age', '>', 200); }); } }
取消全局作用域
如果需要對當前查詢取消全局作用域,需要使用 withoutGlobalScope
方法。 該方法僅接受全局作用域類名作為它唯一的參數:
User::withoutGlobalScope(AgeScope::class)->get();
或者,如果使用閉包定義全局作用域的話:
User::withoutGlobalScope('age')->get();
如果你需要取消部分或者全部的全局作用域的話,需要使用 withoutGlobalScopes
方法:
// 取消所有的全局作用域... User::withoutGlobalScopes()->get(); // 取消部分全局作用域... User::withoutGlobalScopes([ FirstScope::class, SecondScope::class ])->get();
本地作用域
本地作用域允許定義通用的約束集合以便在應用程序中重復使用。例如,你可能經常需要獲取所有 「流行」的用戶。 要定義這樣一個范圍,只需要在對應的 Eloquent 模型方法前添加 scope
前綴:
作用域總是返回一個查詢構造器實例:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 只查詢受歡迎的用戶的作用域. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopePopular($query) { return $query->where('votes', '>', 100); } /** * 只查詢 active 用戶的作用域. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('active', 1); } }
使用本地作用域
一旦定義了作用域,就可以在查詢該模型時調用作用域方法。不過,在調用這些方法時不必包含 scope
前綴。甚至可以鏈式調用多個作用域,例如:
$users = App\User::popular()->active()->orderBy('created_at')->get();
借助 or
查詢運行符整合多個 Eloquent 模型,可能需要使用閉包回調:
$users = App\User::popular()->orWhere(function (Builder $query) { $query->active(); })->get();
因為這樣可能會有點麻煩,Laravel 提供了「高階的」 orWhere
方法,它允許你在鏈式調用作用域時不使用閉包:
$users = App\User::popular()->orWhere->active()->get();
動態(tài)作用域
有時可能地希望定義一個可以接受參數的作用域。把額外參數傳遞給作用域就可以達到此目的。作用域參數要放在 $query
參數之后:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 將查詢作用域限制為僅包含給定類型的用戶。 * * @param \Illuminate\Database\Eloquent\Builder $query * @param mixed $type * @return \Illuminate\Database\Eloquent\Builder */ public function scopeOfType($query, $type) { return $query->where('type', $type); } }
這樣就可以在調用作用域時傳遞參數了:
$users = App\User::ofType('admin')->get();
模型比較
有時可能需要判斷兩個模型是否「相同」。 is
方法可以用來快速校驗兩個模型是否擁有相同的主鍵、表和數據庫連接:
if ($post->is($anotherPost)) { // }
事件
Eloquent 模型觸發(fā)幾個事件,允許你掛接到模型生命周期的如下節(jié)點: retrieved
、 creating
、 created
、 updating
、 updated
、 saving
、 saved
、 deleting
、 deleted
、 restoring
和 restored
。事件允許你每當特定模型保存或更新數據庫時執(zhí)行代碼。每個事件通過其構造器接受模型實例。
retrieved
事件在現有模型從數據庫中查找數據時觸發(fā)。當新模型每一次保存時, creating
和 created
事件被觸發(fā)。如果數據庫中已經存在模型并且調用了 save
方法, updating
/ updated
事件被觸發(fā)。這些情況下, saving
/ saved
事件也被觸發(fā)。
{note} 通過 Eloquent 進行批量更新時,被更新模型的
saved
和updated
事件不會被觸發(fā)。這是因為批量更新時,并沒有真的獲取模型。
首先,在 Eloquent 模型上定義一個 $dispatchesEvents
屬性,將 Eloquent 模型生命周期的幾個節(jié)點映射到你自己的 event 類 :
<?php namespace App; use App\Events\UserSaved; use App\Events\UserDeleted; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ use Notifiable; /** * 為模型事件。 * * @var array */ protected $dispatchesEvents = [ 'saved' => UserSaved::class, 'deleted' => UserDeleted::class, ]; }
定義并且映射了 Eloquent 事件,就可以使用 event 監(jiān)聽器 listeners 處理這些事件了。
觀察者
定義觀察者
如果在一個模型上監(jiān)聽了多個事件,可以使用觀察者來將這些監(jiān)聽器組織到一個單獨的類中。觀察者類的方法名映射到你希望監(jiān)聽的 Eloquent 事件。 這些方法都以模型作為其唯一參數。 make:observer
Artisan 命令可以快速建立新的觀察者類:
php artisan make:observer UserObserver --model=User
此命令將在 App/Observers
文件夾放置新的觀察者類。如果這個目錄不存在,Artisan 將替你創(chuàng)建。使用如下方式開啟觀察者:
<?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 updated(User $user) { // } /** * 處理 User 「刪除」 事件。 * * @param \App\User $user * @return void */ public function deleted(User $user) { // } }
在你希望觀察的模型上使用 observe
方法注冊觀察者。也可以在服務提供者的 boot
方法注冊觀察者。下面是在 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::observe(UserObserver::class); } /** * 注冊服務提供者。 * * @return void */ public function register() { // } }