我們已經學會定義最簡單、一對一的路由。
像是https://myweb.com/
對應首頁、https://myweb.com/about
對應關於頁、https://myweb.com/articles
對應秀出所有文章...
Route::get('/',function(){
return view('home');
});
Route::get('about',function(){
return view('about');
});
Route::get('articles',[App\Http\Controllers\ArticlesController::class,'index']);
但如果要個別秀出單篇文章呢?如果有上千篇文章是不是就要寫上千行路由(route)?Q_Q
Route::get('articles/1',[App\Http\Controllers\ArticlesController::class,'show_1']);
Route::get('articles/2',[App\Http\Controllers\ArticlesController::class,'show_2']);
Route::get('articles/3',[App\Http\Controllers\ArticlesController::class,'show_3']);
Route::get('articles/4',[App\Http\Controllers\ArticlesController::class,'show_4']);
Route::get('articles/5',[App\Http\Controllers\ArticlesController::class,'show_5']);
...
像上面情況,我們想要呼叫幾號文章就秀出幾號文章。
這時候就可以用到Laravel的wildcard!
Route::get('articles/{id}',[App\Http\Controllers\ArticlesController::class,'show']);
有點像變數的概念,大括號裡是變數名稱,之後在那個位置輸入的會變成該變數的值。
在router進入點的地方先這樣定義要輸入的變數(這邊用id為例)。
Route::get('articles/{id}',[App\Http\Controllers\ArticlesController::class,'show']);
在控制器裡,function的括號中寫要帶入的變數($id),這樣在網址輸入的參數就可以被傳到控制器了。
class ArticlesController extends Controller
{
public function show($id)
{
return $id;
}
}
$id
會等於{id}
那輸入的值。例如https://myweb.com/articles/123
,這時候$id
就會是123
在這個用法裡router定義的名字和function定義的變數名字可以不一樣。
Route::get('articles/{any_thing_you_type}',[App\Http\Controllers\ArticlesController::class,'show']);
class ArticlesController extends Controller
{
public function show($id)
{
return $id;
}
}
像這樣也可以work。但通常會定義一樣的名字,比較好管理。
然後也不能什麼都不寫,只有空的大括號{}
。
大部分情況,wildcards輸入的會是model的id,所以傳進控制器後還要用id取得對應的model物件。
比方說要印出某篇文章標題可能會像這樣:
class ArticlesController extends Controller
{
public function show($id)
{
echo Article::find($id)->title;
}
}
但這樣還是有點麻煩,多一個步驟,所以Laravel提供一個簡單的寫法。
class ArticlesController extends Controller
{
public function show(Article $article)
{
echo $article->title;
}
}
只要wildcards輸入的是id,在controller,Laravel會自動幫你找對應的model,這樣寫就不用再find($id)
了!
但前提是在router的命名要是那model的名字,像下面:
Route::get('articles/{article}',[App\Http\Controllers\ArticlesController::class,'show']);