🔏
🔏
🔏
🔏
Laravel 4.2 入門
Search…
🔏
🔏
🔏
🔏
Laravel 4.2 入門
前言
Laravel 介紹
Laravel 介紹
認識 Laravel
開始之前
進入 Laravel 的世界
進入 Laravel 的世界
安裝 Composer
建立 Laravel 專案
Laravel 框架目錄說明
Artisan 常用指令說明
基本配置設定
基本配置設定
設定伺服器
建立開發環境
設定 Laravel 網站
動手做-入門
動手做-入門
Laravel 的 MVC 模型
使用 Route
使用 View
使用 Controller
使用 Migration 和 Model
使用 Form
第一個小專案:迷你部落格
動手做 - 進階
動手做 - 進階
Route 進階
Blade 樣板系統
Form 進階
Form 的資料驗證
資料庫
資料庫
Query Builder
Eloquent ORM
Schema Builder
Migrations & Seeding
常用功能實作
常用功能實作
登入驗證
在地化 (多國語言)
分頁
寄信
附錄
附錄
移除 public 結尾
Sublime Text 的開發套件
Powered By
GitBook
Route 進階
在前一個迷你部落格專案中,我們的 routes.php 最終內容是這樣:
Route::get('post', '
[email protected]
');
Route::get('post/create', '
[email protected]
');
Route::post('post', '
[email protected]
');
Route::get('post/{id}', '
[email protected]
');
Route::get('post/{id}/edit', '
[email protected]
');
Route::put('post/{id}', '
[email protected]
');
Route::delete('post/{id}', '
[email protected]
');
你可以思考一件事,目前我們只開發了一個簡單的文章 CRUD 功能,但是我們的 Route 卻寫了 7 行,當你的網站功能越來越多,Route 的數量肯定會多到難以維護。Laravel 提供了一些方法,可以讓你更好管理 Route。
群組化 (group)
你會注意到,這些功能全都在 post 這個網址之下,因此我們可以將它往上提,改成這樣:
Route::group(['prefix'=>'post'], function(){
Route::get('/', '
[email protected]
');
Route::get('create', '
[email protected]
');
Route::post('/', '
[email protected]
');
Route::get('{id}', '
[email protected]
');
Route::get('{id}/edit', '
[email protected]
');
Route::put('{id}', '
[email protected]
');
Route::delete('{id}', '
[email protected]
');
});
使用 Route::group() 方法可以將位於同一名稱底下的網址群組化。
第一個參數是陣列,['prefix'=>'post'] 的 prefix 是關鍵字,用來指定前置字,因為我們的網址都是以 post 開頭,所以將 post 指定為 prefix。
現在,原本 route 中的 post 就可以移除或改成斜線,這裡的斜線表示為 post 本身。如此在管理上就能很清楚的看到,它們是一夥的。
除了 prefix 關鍵字外,還有 before 及 after 等可以使用。
資源控制器 (Resource controllers)
要使用資源控制器,就要先瞭解 Route 表。首先,開啟終端機,使用 cd 指令進入 blog 網站根目錄,輸入:
php artisan routes
會列出目前建立的所有 Route,如下:
因為這 7 個 Route 是一個基本的 CRUD 流程,經常使用,所以 Route 提供了一個方法,可以幫你自動產生這 7 個 Route。
現在,將 routes.php 中,之前寫的 Route 全部註解掉,改成使用 resourece() 方法:
Route::resource('post', 'HomeController');
存檔,再回到終端機執行同樣的指令,你會得到幾乎相同的 Route 表,如下:
僅多了一行 PATCH。Name 的欄位多了 post.index、post.create...等的名稱,這個是 Route 的名稱。在 Laravel 框架中,你可以使用 URI(前面的範例都是使用這個)或 Name 的方式指定 Route,最後都會由對應的 Action 也就是 Controller 去執行。
所以,現在你可以瞭解,為什麼在 Controller 中,我們要使用這些特定名稱來為方法命名了,因為這樣才能使用資源控制器來簡化 Route 的撰寫。
有時候你並沒有使用到那麼多 Route ,但又想使用資源控制器,你也可以要求 resource 只產生某幾個 Route,使用第三個參數:
Route::resource('post', 'HomeController', ['only' => ['create','store','destroy']]);
第三個參數是陣列型態,可以使用許多條件。使用 'only' 關鍵字,接著給一個陣列的值,其值可以是 index、create、store、show、edit、update、destroy 等值,使用 only 的話,就是有指定的才會建立,其餘的則忽略。
使用 Route Name
之前建立的 Route 都沒有設定 Route 名稱,所以就只能使用 URI 來接受請求。這裡示範 Route Name 怎麼寫:
Route::get('post', array('uses' => '
[email protected]
', 'as' => 'post.home'));
原本第二個參數直接指定
[email protected]
這個 Action。現在把它改為使用陣列,並且使用兩個關鍵字當 key:
'uses' 表示要使用哪個
[email protected]
'as' 表示這個 Route 的 Route Name。
!注意,如果把這行寫在 Route::resource 這行之後,由 resource 產生的相同 URI 的 Route 就會被後面這個 Route 取代(表示不會有重覆的 Route 出現),所以最後的 Route Name 就會是 post.home 而不是 post.index,你可以在終端機下指令觀看 Route 表的變化。
那要怎麼用 Route Name 呢?簡單舉例,在 app/views/home.blade.php 中,原本的
{{ link_to('post/'.$post->id, $post->title) }}
如果使用 Route Name 的方式,要改為:
{{ link_to_route('post.show', $post->title, ['id'=>$post->id]) }}
註:link_to 及 link_to_route 是 3.x 的寫法,在 4.x 之後已經改了寫法,改成
HTML::linkRoute
[1]。要查看
4.x 的 API 在這裡
[2],可以直接搜尋'link',或在左邊清單中,找到 Html -> HtmlBuilder 就可以看到全部可以使用的方法。
所以,在 4.x 之後的版本:
link_to 改為 HTML::link
link_to_route 改為 HTML::linkRoute
參數 (Parameters)
選擇性參數
之前我們寫的
Route::get('post/{id}', '
[email protected]
');
{id} 就是參數。如果這個參數是選擇性的,可以加上問號:
Route::get('post/{id?}', '
[email protected]
');
後面加個問號,當網址是
http://localhost/blog/public/post
或
http://localhost/blog/public/post/1
都會由這個 Route 處理。因為在我們的例子中,已經有 "沒有$id" 的 Route 了,所以要小心衝突的發生。
在我們的例子中,如果要使用選擇性參數,可以先將
Route::get('post', '
[email protected]
');
這行註解掉,就不能作用了,現在連到這個網址就會出錯
http://localhost/blog/public/post
現在,把
[email protected]
的 Route 的 {id?} 加上問號。接著修改 HomeController 的 show() 為:
public function show($id=null)
{
if (is_null($id)) {
return $this->index();
}
//下略...
這樣當 $id 為 null 時,就會轉給 index() 去處理。這裡只是舉例,請在必要的時候才這麼做。
參數的條件限制
串接 where() 方法可做條件限制:
Route::get('post/{id}', '
[email protected]
')->where('id', '[0-9]+');
條件限制是以正規表示式來描述。但是因為為我們的
[email protected]
本來就無法處理 id 非數字的情況,所以無論有沒有加條件限制都會發生錯誤,在於錯誤會不同。
當輸入的 id 不是數字,在加了條件限制的 URI 中,這個請求不會被送入 Controller,而是出現找不到對應的 Route 的錯誤。在加條件限制之前,非數字的 id 仍會送進 Controller,但在 Model 查詢資料庫時,會因為資料型態不符合(id必須為數值)而出現錯誤,這時候會是資料庫查詢錯誤。
你也可以把模式寫成全域的
Route::pattern('id', '[0-9]+');
記得要寫在最上面,這樣會影響之後所有參數為 id 的 Route。
過濾器(filter)
Route 還可以設定過濾器,在執行某個網址之前,先做一些檢查。這些過濾器另外寫在 app/filters.php 檔案裡。之後我們會用到 auth 這個內建的過濾器來做登入的驗證。
Model 綁定(Model Binding)
Route 提供 Model 及資料表的綁定,
Route::model('pp', 'Post');
Route::get('p/{pp}', function(Post $post)
{
return $post->title;
});
我們把 pp 和 Post Model 綁定,這時候只要使用參數 {pp} 就會得到一個 Post 物件。也就是
http://localhost/blog/public/p/1
中的 1 會送入 {pp} 所綁定的 Post 物件,並以 id 查詢後,傳回給 $post 變數,然後就可以使用 $post->title 取得標題。
[1]
http://laravel.com/api/4.2/Illuminate/Html/HtmlBuilder.html#method_linkRoute
[2]
http://laravel.com/api/4.2/index.html
動手做 - 進階 - Previous
動手做 - 進階
Next - 動手做 - 進階
Blade 樣板系統
Last modified
2yr ago
Copy link
Outline
群組化 (group)
資源控制器 (Resource controllers)
使用 Route Name
參數 (Parameters)
選擇性參數
參數的條件限制
過濾器(filter)
Model 綁定(Model Binding)