路由模型綁定
普通方法:
Route::get('/article/{id}', function($id){
$article = \App\User::find($id);
}
修改服務提供者實現綁定:
修改RouteServiceProvider
中的boot
方法,此時每一個參數的id
值都會被對應爲一個Article
實例。
public function boot(Router $router)
{
$router->model('article', Article::class);
parent::boot($router);
}
顯式綁定:
同樣是修改RouteServiceProvider
中的boot
方法,在其中顯示指定綁定關係,同時還可以添加異常處理
public function boot(Router $router)
{
$router->bind('article', Article::class, function() {
throw new NotFoundHttpException; //閉包函數用於處理異常
});
parent::boot($router);
}
隱式綁定:
隱式綁定只需在路由定義中的閉包函數或者是控制器的函數中聲明參數(該參數應該與路由參數一致)即可
Route::get('/article/{article}', function(\App\Article $article) {
dd ($article)
}
路由 Resource
Route::resource('users', 'UsersController');
該方法一條語句等同於:
Route::get('/users', 'UsersController@index')->name('users.index');
Route::get('/users/{user}', 'UsersController@show')->name('users.show');
Route::get('/users/create', 'UsersController@create')->name('users.create');
Route::post('/users', 'UsersController@store')->name('users.store');
Route::get('/users/{user}/edit', 'UsersController@edit')->name('users.edit');
Route::patch('/users/{user}', 'UsersController@update')->name('users.update');
Route::delete('/users/{user}', 'UsersController@destroy')->name('users.destroy');
API:
資源類:
資源類用於將給定模型轉換成爲數組,默認存放路徑爲app/Http/Resourcces
,生成命令如下:
php artisan make:resource ArticleResource
如果需要對生成的數據進行選擇性展示,可以對toArray()
進行修改,比如:
return [
'type' => 'article',
'id' => (string)$this->id,
'article' => [
'title' => $this->title,
'content' => $this->content,
],
'category' => new ArticleCategoryResource($this->cate), //利用資源集合獲取分類(不止一個)
'urls' => url('api/articles/'.$this->id),
];
資源集合:
資源集合用於轉換整個模型集合,創建時需要用--collection
標識或者是在名字中含有collection
以便框架能夠區分是否生成爲資源集合類
php artisan make:resource CategoryCollection //方法1
php artisan make:resource --collection Category //方法2
資源類和資源集合類的使用場景:
資源類常用於單個數據,但是所有的資源類都提供了collection
方法,可以生成符合資源類要求的資源集合,但是這種方式生成的資源集合不支持添加元信息。在路由或控制器中用以下語句即可調用
return ArticleResource::collection(Article::paginate()); //此處返回分頁後的資源集合
如果需要和集合同步返回一些元數據,就需要單獨定義一個資源類,定義方法如上所述。定義之後按照需求修改toArray
中的內容,最後的調用方法同資源類一樣,但是這種方式不支持數據內容的定製。
return new AllArticleResource(Article::paginate());
兩者各有其特點,資源類能定製數據格式,但是不支持元數據的添加;資源集合能支持元數據的添加,但是不支持數據格式定製。這裏可以通過在資源集合中調用資源類來同時實現兩者功能,只需在資源集合的toArray
函數中調用資源類,如下所示:
return [
'data' => ArticleResource::collection($this->collection), // 調用資源類
'links' => [
'self' => 'link-value'
]
];
數據包裝:
默認資源類返回的json
數據包裹在data
字段中,如果不需要則可以在請求的地方(通常是控制器)或AppServiceProvider
的boot
方法中寫入:
Resource::withoutWrapping()
添加元數據:
方法1:在return
處進行修改
return [
'data' => parent::toArray($request),
'links' => [
'self' => 'link-value',
],
];
方法2:利用with
函數直接修改頂層元數據
public function with($request)
{
return [
'links' => [
'self' => url('api/articles/'.$this->id),
],
];
}
分頁:
需要分頁時在請求的地方寫成如下形式即可:
return new ArticleResource(Article::paginate()); // 分頁,分頁時withoutWeapping無效
關聯關係(程序層面的外鍵實現):
關聯關係理解的典型的場景如一個作者對應多個文章。實現時先在模型類(此處是Article
)中定義外鍵的方法,聲明外鍵
public function cate()
{
return $this->hasMany(Category::class, 'id', 'category_id'); //參數1是關聯表名,參數2是外鍵字段名(關聯表中的主鍵),參數3是本表中的對應外鍵的字段
}
如果需要修改修改關聯關係得到的結果,則可以定義個資源類或資源集合類,在其中進行修改
return [
'cate_id' => $this->first()->id, //此處關聯獲取的是一個列表,所以需要first
'name' => $this->first()->name,
];
在一開始的資源類中調用外鍵:
[
// ...
'category' => new ArticleCategoryResource($this->cate),
]
兩者ArticleCategoryResource
中return
分別對應的如下的解析方式:
'cate_id' => $this->first()->id, //此處關聯獲取的是一個列表(原本是一對多的場景,此處演示爲一對一)
其它
className::class
指代該類完全命名空間的路徑N + 1
查詢是指數據庫中對某個表做1
次查詢需要對其它表做N
次查詢Laravel dd
函數等同dump()
+die()
,打印出變量並結束腳本運行- 更多(帶條件的屬性、合併帶條件的屬性、帶條件的關聯關係等)請查看
Laravel api
文檔