Laravel Eloquent ORM

Eloquent ORM

簡介

Laravel 自帶的 Eloquent ORM 爲您的數據庫提供了一個優雅的、簡單的 ActiveRecord 實現。每個數據庫的表有一個對應的 "Model" 用來與這張表交互。php

在開始以前,確認已在 app/config/database.php 文件中配置好數據庫鏈接。laravel

基本用法

首先,建立一個 Eloquent 模型。模型一般在 app/models 目錄,可是您能夠自由地把它們放在任何地方,只要它能根據您的 composer.json 文件自動加載。git

定義一個 Eloquent 模型github

classUserextendsEloquent{}

注意咱們並無告訴 Eloquent 咱們爲 User 模型使用了哪一張表。類名的小寫、複數的形式將做爲表名,除非它被顯式地指定。因此,在這種狀況下,Eloquent 將假設 User 模型在 users 表中保存記錄。您能夠在模型中定義一個 table 屬性來指定一個自定義的表名:數據庫

classUserextendsEloquent{protected $table ='my_users';}

注意: Eloquent 將假設每張表有一個名爲 id 的主鍵。您能夠定義 primaryKey 屬性來覆蓋這個約定。一樣,您能夠定義一個 connection 屬性來覆蓋在使用這個模型時所用的數據庫鏈接。json

一旦模型被定義,您能夠開始在表中檢索和建立記錄。注意在默認狀況下您將須要在表中定義 updated_at 和created_at 字段。若是您不但願這些列被自動維護,在模型中設置 $timestamps 屬性爲 false數組

獲取全部記錄緩存

$users=User::all();

根據主鍵獲取一條記錄安全

$user=User::find(1); var_dump($user->name);

注意: 全部在 [查詢構建器] 中適用的函數在 Eloquent 模型的查詢中一樣適用。app

根據主鍵獲取一條記錄或者拋出一個異常

有時您可能但願當記錄沒有被找到時拋出一個異常,容許您使用 App::error 處理器捕捉這些異常並顯示404頁面。

$model=User::findOrFail(1);$model=User::where('votes','>',100)->firstOrFail();

註冊錯誤處理器,請監聽 ModelNotFoundException

useIlluminate\Database\Eloquent\ModelNotFoundException;App::error(function(ModelNotFoundException $e){returnResponse::make('Not Found',404);});

使用 Eloquent 模型查詢

$users=User::where('votes','>',100)->take(10)->get();foreach($usersas$user){ var_dump($user->name);}

固然,您也可使用查詢構建器的統計函數。

Eloquent 統計

$count=User::where('votes','>',100)->count();

若是您沒法經過經過連貫的接口產生查詢,可使用 whereRaw

$users=User::whereRaw('age > ? and votes = 100', array(25))->get();

Chunking Results

If you need to process a lot (thousands) of Eloquent records, using the chunk command will allow you to do without eating all of your RAM:

User::chunk(200,function($users){foreach($usersas$user){//}});

The first argument passed to the method is the number of records you wish to receive per "chunk". The Closure passed as the second argument will be called for each chunk that is pulled from the database.

指定查詢的數據庫鏈接

您可能須要在運行一個 Eloquent 查詢的時候指定數據庫鏈接,只須要使用 on 函數:

$user=User::on('connection-name')->find(1);

集體賦值

當建立一個新的模型,您能夠傳遞屬性的數組到模型的構造函數。這些屬性將經過集體賦值分配給模型。這是很方便的,但把用戶的輸入盲目地傳給模型多是一個嚴重的安全問題。若是把用戶輸入盲目地傳遞給模型,用戶能夠自由地修改任何或者所有模型的屬性。基於這個緣由,默認狀況下全部 Eloquent 模型將防止集體賦值。

首先,在模型中設置 fillable 或 guarded 屬性。

fillable 屬性指定哪些屬性能夠被集體賦值。這能夠在類或接口層設置。

在模型中定義 Fillable 屬性

classUserextendsEloquent{protected $fillable = array('first_name','last_name','email');}

在這個例子中,只有三個被列出的屬性能夠被集體賦值。

fillable 的反義詞是 guarded,將作爲一個黑名單而不是白名單:

在模型中定義 Guarded 屬性

classUserextendsEloquent{protected $guarded = array('id','password');}

在這個例子中,id 和 password 屬性將被容許集體賦值。全部其餘屬性將被容許集體賦值。您可使用 guard 方法阻止全部屬性被集體賦值:

阻止全部屬性集體賦值

protected$guarded=array('*');

插入、更新、刪除

爲了從模型中向數據庫中建立一個新的記錄,簡單地建立一個模型實例並調用 save 函數。

保存一個新的模型

$user=newUser;$user->name ='John';$user->save();

注意: 一般您的 Eloquent 模型將有自動遞增的鍵。然而,若是您但願指定您自定義的鍵,在模型中設置incrementing 屬性爲 false

您也可使用 create 函數在一行代碼中保存一個新的模型。被插入的模型實例將從函數中返回。可是,在您這樣作以前,您須要在模型中指定 fillable 或者 guarded 屬性,由於全部 Eloquent 模型默認阻止集體賦值。

在保存或建立一個使用自增ID的新模型以後,能夠經過對象的 id 屬性獲取此自增ID:

$insertedId=$user->id;

在模型中設置 Guarded 屬性

classUserextendsEloquent{protected $guarded = array('id','account_id');}

使用模型的 Create 函數

// Create a new user in the database... $user =User::create(array('name'=>'John'));// Retrieve the user by the attributes, or create it if it doesn't exist... $user =User::firstOrCreate(array('name'=>'John'));// Retrieve the user by the attributes, or instantiate a new instance... $user =User::firstOrNew(array('name'=>'John'));

爲了更新一個模型,您能夠檢索它,改變一個屬性,而後使用 save 函數:

更新一個檢索到的模型

$user=User::find(1);$user->email ='john@foo.com';$user->save();

有時您可能但願不只保存模型,還有它的全部關係。爲此,您可使用 push 函數:

保存一個模型和關係

$user->push();

您也能夠在一組模型上運行更新:

$affectedRows=User::where('votes','>',100)->update(array('status'=>2));

刪除一個模型,在實例中調用 delete 函數:

刪除一個存在的模型

$user=User::find(1);$user->delete();

根據主鍵刪除一個模型

User::destroy(1);User::destroy(array(1,2,3));User::destroy(1,2,3);

固然,您能夠在一組模型中運行刪除查詢:

$affectedRows=User::where('votes','>',100)->delete();

若是您但願簡單的在一個模型中更新時間戳,可使用 touch 函數:

只更新模型的時間戳

$user->touch();

軟刪除

當軟刪除一個模型,它並無真的從數據庫中刪除。相反,一個 deleted_at 時間戳在記錄中被設置。爲一個模型開啓軟刪除,在模型中指定 softDelete 屬性:

classUserextendsEloquent{protected $softDelete =true;}

爲了在您的表中添加一個 deleted_at 字段,您能夠在遷移中使用 softDeletes 函數:

$table->softDeletes();

如今,當您在一個模型中調用 delete 函數,deleted_at 字段將被設置爲當前的時間戳。在使用軟刪除的模型中查詢,被軟刪除的模型將不被包含進查詢結果中。爲了強制已刪除的模型出如今結果集中,在查詢中使用withTrashed 函數:

強制軟刪除的模型到結果集中

$users=User::withTrashed()->where('account_id',1)->get();

若是您但願在結果集中包含軟刪除的模型,您可使用 onlyTrashed 函數:

$users=User::onlyTrashed()->where('account_id',1)->get();

恢復一個已被軟刪除的記錄,使用 restore 函數:

$user->restore();

您也能夠在查詢中使用 restore 函數:

User::withTrashed()->where('account_id',1)->restore();

restore 函數也能夠在關係中被使用:

$user->posts()->restore();

若是您但願從數據庫中真正刪除一個模型,您可使用 forceDelete 函數:

$user->forceDelete();

forceDelete 函數也能夠在關係中被使用:

$user->posts()->forceDelete();

檢測一個給定的模型實例是否被軟刪除,可使用 trashed 函數:

if($user->trashed()){//}

時間戳

默認狀況下,Eloquent 在數據的表中自動地將維護 created_at 和 updated_at 字段。只需簡單的添加這些timestamp 字段到表中,Eloquent 將爲您作剩餘的工做。若是您不但願 Eloquent 維護這些字段,在模型中添加如下屬性:

禁止自動時間戳

classUserextendsEloquent{protected $table ='users';public $timestamps =false;}

若是您但願定製時間戳的格式,能夠在模型中重寫 getDateFormat 函數:

提供一個定製的時間戳格式

classUserextendsEloquent{protectedfunction getDateFormat(){return'U';}}

查詢範圍

範圍容許您容易在模型中重用查詢邏輯。定義一個範圍,簡單的用 scope 爲模型添加前綴:

定義一個查詢範圍

classUserextendsEloquent{publicfunctionscopePopular($query){return$query->where('votes','>',100);}publicfunctionscopeWomen($query){return$query->whereGender('W');}}

使用一個查詢範圍

$users=User::popular()->women()->orderBy('created_at')->get();

動態範圍

有時您可能但願定義一個接受參數的範圍。只須要添加您的參數到您的範圍函數:

classUserextendsEloquent{publicfunction scopeOfType($query, $type){return $query->whereType($type);}}

而後在範圍函數調用中傳遞參數:

$users=User::ofType('member')->get();

關係

固然,您的數據庫多是彼此相關的。好比,一篇博客文章可能有許多評論,或者一個訂單與下訂單的用戶相關。Eloquent 使得管理和處理這些關係變得簡單。Laravel 提供了四種類型的關係:- 一對一一對多多對多-Has Many Through多態關係

一對一

一個一對一關係是一種很是基礎的關係。好比,一個 User 模型能夠有一個 Phone`。咱們能夠在 Eloquent 中定義這個關係:

定義一個一對一關係

classUserextendsEloquent{publicfunction phone(){return $this->hasOne('Phone');}}

傳遞給 hasOne 函數的第一個參數是相關模型的名字。一旦這個關係被定義,咱們可使用 Eloquent 的 [動態屬性] 獲取它:

$phone=User::find(1)->phone;

這條語句所產生的 SQL 語句以下:

select*from users where id =1select*from phones where user_id =1

注意 Eloquent 假設關係的外鍵基於模型的名字。在這個例子中假設 Phone 模型使用一個 user_id 外鍵。若是您但願覆蓋這個慣例,您能夠爲傳遞 hasOne 函數傳遞第二個參數。Furthermore, you may pass a third argument to the method to specify which local column that should be used for the association:

return$this->hasOne('Phone','foreign_key');return$this->hasOne('Phone','foreign_key','local_key');

在 Phone 模型定義逆向關係,咱們使用 belongsTo 函數:

定義一個逆向關係

classPhoneextendsEloquent{publicfunction user(){return $this->belongsTo('User');}}

在上面的例子中,Eloquent 將在 phones 表中尋找 user_id 字段。若是您想定義一個不一樣的外鍵字段,您能夠經過 belongsTo 函數的第二個參數傳遞它:

classPhoneextendsEloquent{publicfunction user(){return $this->belongsTo('User','local_key');}}

Additionally, you pass a third parameter which specifies the name of the associated column on the parent table:

classPhoneextendsEloquent{publicfunction user(){return $this->belongsTo('User','local_key','parent_key');}}

一對多

一個一對多關係的例子是一篇博客文章有許多評論。咱們能夠像這樣定義關係模型:

classPostextendsEloquent{publicfunction comments(){return $this->hasMany('Comment');}}

如今咱們能夠經過 動態屬性 訪問文章的評論:

$comments=Post::find(1)->comments;

若是您須要添加進一步的約束檢索哪些評論,咱們能夠調用 comments 函數鏈接鏈式條件:

$comments=Post::find(1)->comments()->where('title','=','foo')->first();

再次,若是您想覆蓋默認的外鍵,能夠給 hasMany 函數傳遞第二個參數。And, like the hasOne relation, the local column may also be specified:

return$this->hasMany('Comment','foreign_key');return$this->hasMany('Comment','foreign_key','local_key');

在 Comment 模型中定義逆向關係,咱們使用 belongsTo 函數:

定義逆向關係

classCommentextendsEloquent{publicfunction post(){return $this->belongsTo('Post');}}

多對多

多對多關係更復雜的關係類型。這種關係的一個例子是一個用戶和角色,這個角色也可被其餘用戶共享。好比,許多用戶有 "Admin" 的角色。這個關係須要三個表:usersroles 以及 role_userrole_user 表來源於相關的角色名,而且有 user_id 和 role_id 字段。

咱們可使用 belongsToMany 函數定義一個多對多關係:

classUserextendsEloquent{publicfunction roles(){return $this->belongsToMany('Role');}}

如今,咱們能夠經過 User 模型獲取角色:

$roles=User::find(1)->roles;

若是您想使用一個很是規的表名做爲關係表,您能夠傳遞它做爲第二個參數給 belongsToMany 函數:

return$this->belongsToMany('Role','user_roles');

您也能夠覆蓋相關的鍵:

return $this->belongsToMany('Role','user_roles','user_id','foo_id');

固然,您也能夠定義在 Role 模型中定義逆向關係:

classRoleextendsEloquent{publicfunction users(){return $this->belongsToMany('User');}}

Has Many Through

The "has many through" relation provides a convenient short-cut for accessing distant relations via an intermediate relation. For example, a Country model might have many Posts through a Users model. The tables for this relationship would look like this:

countries id-integername-string users id-integer country_id -integername-string posts id-integer user_id -integer title -string

Even though the posts table does not contain a country_id column, the hasManyThrough relation will allow us to access a country's posts via $country->posts. Let's define the relationship:

classCountryextendsEloquent{publicfunction posts(){return $this->hasManyThrough('Post','User');}}

If you would like to manually specify the keys of the relationship, you may pass them as the third and fourth arguments to the method:

classCountryextendsEloquent{publicfunction posts(){return $this->hasManyThrough('Post','User','country_id','user_id');}}

多態關係

多態關係容許在一個關聯中一個模型屬於多於一個的其餘模型。好比,您可能有一個 photo 模型屬於一個員工模型或者一個訂單模型。咱們能夠定義像這樣定義這個關係:

classPhotoextendsEloquent{publicfunction imageable(){return $this->morphTo();}}classStaffextendsEloquent{publicfunction photos(){return $this->morphMany('Photo','imageable');}}classOrderextendsEloquent{publicfunction photos(){return $this->morphMany('Photo','imageable');}}

如今,咱們能夠爲一個員工或者一個訂單獲取照片:

獲取一個多態關係

$staff=Staff::find(1);foreach($staff->photos as$photo){//}

然而,"polymorphic" 的真正魔力是當您從 Photo 模型中訪問員工或者訂單的時候:

獲取多態關係的屬主

$photo=Photo::find(1);$imageable=$photo->imageable;

Photo 模型的 imageable 關係將返回一個 Staff 或者 Order 實例,依賴於那種類型的模型擁有這個照片。

幫助理解這是怎樣工做的,讓咱們探討一個多態關係的數據庫結構:

多態關係的數據庫結構

staff id-integername-string orders id-integer price -integer photos id-integer path -string imageable_id -integer imageable_type -string

這裏須要注意的鍵字段是表 photos 的 imageable_id 和 imageable_type 字段。ID 將包含所屬員工或訂單的 ID,類型將包含所屬模型的類名。當訪問 imageable 關係的時候將容許 ORM 檢測所屬模型的類型。

查詢關係

當爲一個模型獲取記錄的時候,您可能但願基於一個已存在的關係限制結果集的數目。好比,您但願獲取至少有一條評論的文章。爲此,您可使用 has 函數:

Querying Relations When Selecting

$posts=Post::has('comments')->get();

您也能夠指定一個操做符和數量:

$posts=Post::has('comments','>=',3)->get();

If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries:

$posts=Post::whereHas('comments',function($q){$q->where('content','like','foo%');})->get();

動態屬性

Eloquent 容許您經過動態屬性訪問關係。Eloquent 將爲您自動加載關係,而且足夠聰明到知道是否調用 get(爲一對多關係)或者 first (爲一對一關係)。而後,它將經過動態屬性訪問做爲關係。好比,使用下面的 Phone 模型:

classPhoneextendsEloquent{publicfunction user(){return $this->belongsTo('User');}} $phone =Phone::find(1);

不須要像這樣打印用戶的電子郵件:

echo $phone->user()->first()->email;

它能夠簡化爲:

echo $phone->user->email;

注意: 返回多個結果的關係,其本質是返回了 Illuminate\Database\Eloquent\Collection 類的一個實例。

預先加載

預先加載的存在是爲了緩解 N + 1 查詢問題。好比,考慮一個 Author 相關的 Book 模型。關係定義是這樣的:

classBookextendsEloquent{publicfunction author(){return $this->belongsTo('Author');}}

如今,考慮下面的代碼:

foreach(Book::all()as$book){ echo $book->author->name;}

此循環將執行一個查詢獲取表中的全部書籍,而後另外一個查詢爲每本書獲取做者。因此,若是咱們有 25 本書,這個循環將容許 26 個查詢。

值得慶幸的是,咱們可使用預先加載來減小查詢的數量。這個關係應該被預先加載經過 with 函數指定:

foreach(Book::with('author')->get()as$book){ echo $book->author->name;}

在上面的循環中,只有兩個查詢被執行:

select*from books select*from authors where id in(1,2,3,4,5,...)

明智的使用預先加載能夠大大提升應用程序的性能。

固然,您能夠一次性預先加載多個關係:

$books=Book::with('author','publisher')->get();

您甚至能夠預先加載嵌套關係:

$books=Book::with('author.contacts')->get();

在上面的例子中,author 關係將被預先加載,並且做者的 contacts 關係也將被加載。

預先加載約束

有時您可能但願預先加載一個關係,但也爲預先加載指定一個條件。這裏是一個例子:

$users=User::with(array('posts'=>function($query){$query->where('title','like','%first%');}))->get();

在這個例子中,咱們預先加載用戶的文章,但只限於文章的 title 字段中包含單詞 "first" 的文章:

延遲預先加載

從一個已存在的模型中直接預先加載相關的模型也是可能的。這在動態的決定是否加載相關模型或與緩存結合時可能有用。

$books=Book::all();$books->load('author','publisher');

插入相關模型

您會常常須要插入新的相關模型。好比,你可能但願爲一篇文章插入一條新的評論。不須要在模型中手動設置post_id 外鍵,您能夠直接從它的父模型 Post 中插入新的評論:

附加一個相關的模型

$comment=newComment(array('message'=>'A new comment.'));$post=Post::find(1);$comment=$post->comments()->save($comment);

在這個例子中,所插入評論的 post_id 字段將自動設置。

相關模型 (屬於)

當更新一個 belongsTo 關係,您可使用 associate 函數,這個函數將爲子模型設置外鍵:

$account=Account::find(10);$user->account()->associate($account);$user->save();

插入相關模型 (多對多)

當處理多對多關係時,您也能夠插入相關模型。讓咱們繼續使用咱們的 User 和 Role 模型做爲例子。咱們可以輕鬆地使用 attach 函數爲一個用戶附加新的角色:

附加多對多模型

$user=User::find(1);$user->roles()->attach(1);

您也能夠傳遞一個屬性的數組,存在關係的表中:

$user->roles()->attach(1, array('expires'=>$expires));

固然,attach 的反義詞是 detach

$user->roles()->detach(1);

您也可使用 sync 函數附加相關的模型。sync 函數接受一個 IDs 數組。當這個操做完成,只有數組中的 IDs 將會爲這個模型存在關係表中:

使用 Sync 附加多對多關係

$user->roles()->sync(array(1,2,3));

您也能夠用給定的 IDs 關聯其餘關係表中的值:

同步時添加關係數據

$user->roles()->sync(array(1=>array('expires'=>true)));

有時您可能但願建立一個新的相關的模型,而且在一行中附加它。對於此操做,您可使用 save 函數:

$role=newRole(array('name'=>'Editor'));User::find(1)->roles()->save($role);

在這個例子中,新的 Role 模型將被保存並附加到用戶模型。您也能夠傳遞一個屬性的數組加入到在這個操做中所鏈接的表:

User::find(1)->roles()->save($role, array('expires'=>$expires));

觸發父模型時間戳

當一個模型 belongsTo 另外一個模型,好比一個 Comment 屬於一個 Post,當更新子模型時更新父模型的時間戳一般是有用的。好比,當一個 Comment 模型更新,您想自動更新所屬 Post 的 updated_at 時間戳。Eloquent 使之變得容易,只須要在子模型中添加 touches 屬性包含關係的名字:

classCommentextendsEloquent{protected $touches = array('post');publicfunction post(){return $this->belongsTo('Post');}}

如今,當您更新一個 Comment,所屬的 Post 的 updated_at 字段也將被更新:

$comment=Comment::find(1);$comment->text ='Edit to this comment!';$comment->save();

與數據透視表工做

正如您已經瞭解到,使用多對多關係須要一箇中間表的存在。Eloquent 提供了一些很是有用與這個表交互的方式。好比,讓咱們假設咱們的 User 對象有不少相關的 Role 對象,在訪問這個關係時,咱們能夠在這些模型中訪問數據透視表:

$user=User::find(1);foreach($user->roles as$role){ echo $role->pivot->created_at;}

注意每個咱們檢索的 Role 模型將自動賦值給一個 pivot 屬性。這個屬性包含一個表明中間表的模型,而且能夠像其餘 Eloquent 模型使用。

默認狀況下,在 pivot 對象中只有鍵,若是您的數據透視表包含其餘的屬性,您必須在定義關係時指定它們:

return$this->belongsToMany('Role')->withPivot('foo','bar');

如今,foo 和 bar 屬性將能夠經過 Role 模型的 pivot 對象中訪問。

若是您想您的數據透視表有自動維護的 created_at 和 updated_at 時間戳,在關係定義時使用withTimestamps 方法:

return$this->belongsToMany('Role')->withTimestamps();

爲一個模型在數據透視表中刪除全部記錄,您可使用 detach 函數:

在一個數據透視表中刪除記錄

User::find(1)->roles()->detach();

注意這個操做並不從 roles 刪除記錄,只從數據透視表中刪除。

Defining A Custom Pivot Model

Laravel also allows you to define a custom Pivot model. To define a custom model, first create your own "Base" model class that extends Eloquent. In your other Eloquent models, extend this custom base model instead of the default Eloquent base. In your base model, add the following function that returns an instance of your custom Pivot model:

publicfunctionnewPivot(Model$parent, array $attributes,$table,$exists){returnnewYourCustomPivot($parent,$attributes,$table,$exists);}

集合

全部經過 get 方法或一個relationship由Eloquent返回的多結果集都是一個集合對象。這個對象實現了IteratorAggregate PHP 接口,因此能夠像數組同樣進行遍歷。然而,這個對象也有不少其餘的函數來處理結果集。

好比,咱們可使用 contains 檢測一個結果集是否包含指定的主鍵:

檢測一個集合是否包含一個鍵

$roles=User::find(1)->roles;if($roles->contains(2)){//}

集合也能夠被轉換爲一個數組或JSON:

$roles=User::find(1)->roles->toArray();$roles=User::find(1)->roles->toJson();

若是一個集合被轉換爲一個字符轉,它將以JSON格式返回:

$roles=(string)User::find(1)->roles;

Eloquent 集合也包含一些方法來遍歷和過濾所包含的項:

遍歷集合

$roles=$user->roles->each(function($role){//});

過濾集合

過濾集合時,你所提供的回調函數將被做爲 array_filter 的回調函數使用。

$users=$users->filter(function($user){if($user->isAdmin()){return$user;}});

注意: 當過濾集合並轉化爲JSON格式時,應首先調用 values 函數重置數組內全部的鍵(key)。

對每一個集合項應用回調函數

$roles=User::find(1)->roles;$roles->each(function($role){//});

根據一個值排序集合

$roles=$roles->sortBy(function($role){return$role->created_at;});

有時,您可能但願返回一個自定義的集合以及本身添加的函數。您能夠經過在 Eloquent 模型中重寫newCollection 函數指定這些:

返回一個自定義集合類型

classUserextendsEloquent{publicfunction newCollection(array $models = array()){returnnewCustomCollection($models);}}

訪問器和調整器

Eloquent 爲獲取和設置模型的屬性提供了一種便利的方式。簡單的在模型中定義一個 getFooAttribute 函數聲明一個訪問器。記住,這個函數應該遵循 "camel-casing" 拼寫格式,即便您的數據庫使用 "snake-case":

定義一個訪問器

classUserextendsEloquent{publicfunction getFirstNameAttribute($value){return ucfirst($value);}}

在上面的例子中,first_name 字段有一個訪問器。注意屬性的值被傳遞到訪問器。

調整器以相似的方式聲明:

定義一個調整器

classUserextendsEloquent{publicfunction setFirstNameAttribute($value){ $this->attributes['first_name']= strtolower($value);}}

日期調整器

默認狀況下,Eloquent 將轉換 created_atupdated_at 以及 deleted_at 字段爲 Carbon 的實例,它提供了各類有用的函數,而且繼承自原生 PHP 的 DateTime 類。

您能夠指定哪些字段自動調整,設置禁用調整,經過在模型中重寫 getDates 函數:

publicfunctiongetDates(){returnarray('created_at');}

當一個字段被認爲是一個日期,您能夠設置它的值爲一個 UNIX 時間戳,日期字符串 (Y-m-d),日期時間字符串,固然也能夠是一個 DateTime 或 Carbon 實例。

徹底禁用日期調整,從 getDates 函數中返回一個空數組:

publicfunctiongetDates(){returnarray();}

模型事件

Eloquent 模型觸發一些事件,容許您使用如下函數在模型的生命週期內的許多地方插入鉤子:creatingcreatedupdating、 updatedsavingsaveddeletingdeletedrestoringrestored

每當一個新的項目第一次被保存,creating 和 created 事件將被觸發。若是一個項目不是新的而且 save 函數被調用, updating/updated 事件將被觸發。在這兩種狀況下,saving/saved 事件都將被觸發。

若是從 creatingupdating 或者 saving 返回 false ,該操做將被取消:

經過事件取消保存操做

User::creating(function($user){if(!$user->isValid())returnfalse;});

Eloquent 模型也包含一個靜態的 boot 函數,它能夠提供一個方便的地方註冊事件綁定。

設置一個模型 Boot 函數

classUserextendsEloquent{publicstaticfunction boot(){ parent::boot();// Setup event bindings...}}

模型觀察者

爲增強處理模型事件,您能夠註冊一個模型觀察者。一個觀察者類能夠包含不少函數對應於不少模型事件。好比,creatingupdatingsaving 函數能夠在一個觀察者中,除其餘模型事件名以外。

所以,好比,一個模型觀察者能夠像這樣:

classUserObserver{publicfunctionsaving($model){//}publicfunctionsaved($model){//}}

您可使用 observe 函數註冊一個觀察者實例:

User::observe(newUserObserver);

轉爲數組或JSON

當構建JSON APIs,您可能常常須要轉換您的模型和關係爲數組或JSON字符串。因此,Eloquent 包含這些方法。轉換一個模型和它加載的關係爲一個數組,您可使用 toArray 函數:

轉換一個模型爲數組

$user=User::with('roles')->first();return$user->toArray();

注意模型的所有集合也能夠被轉爲數組:

returnUser::all()->toArray();

轉換一個模型爲JSON字符串,您可使用 toJson 函數:

轉換一個模型爲JSON字符串

returnUser::find(1)->toJson();

注意當一個模型或集合轉換爲一個字符串,它將轉換爲JSON,這意味着您能夠直接從應用程序的路由中返回 Eloquent 對象!

從路由中返回一個模型

Route::get('users',function(){returnUser::all();});

有時您可能但願限制包含在模型數組或JSON中的屬性,好比密碼,爲此,在模型中添加一個隱藏屬性:

從數組或JSON轉換中隱藏屬性

classUserextendsEloquent{protected $hidden = array('password');}

注意: 若是關係被隱藏了,請使用關係的 method 名稱,而不是動態的訪問名稱。

或者,您可使用 visible 屬性定義一個白名單:

protected $visible =array('first_name','last_name');

某些時候,你可能須要向數據庫添加一組屬性,而這組屬性並在數據庫中沒有對應的字段。爲了可以實現這一需求,能夠簡單的爲每一個屬性定義一個訪問器:

publicfunctiongetIsAdminAttribute(){return$this->attributes['admin']=='yes';}

一旦建立了訪問器,只需將屬性添加到模型的appends屬性中:

protected$appends=array('is_admin');

一旦將屬性添加到appends列表中,它就將被包含在模型和JSON表單中。

相關文章
相關標籤/搜索