路由表位於 routes/
中,有 api.php
, channels.php
, console.php
, web.php
四個檔案。在本篇討論中僅關注 web.php
。
我們可以用 Route
定義一個路由
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/', fn() => 'Hello World');
此時,啟動 Built-in Web Server 之後,瀏覽 [http://127.0.0.1/](http://127.0.0.1/)
即可看到 Hello World
fn() => 'Hello World'
是 PHP 7.4 後的 Arrow Functions Feature,其語法等同於 function() { return 'Hello World'; }
同時,我們也可以指定不同的 HTTP Methods 給各路由
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
或是讓多個不同的 HTTP Methods 有相同的行為
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
// 當 GET 或 POST 時,具有相同行為
Route::match(['get', 'post'], '/', $callback);
// 無論 HTTP Method 是什麼的時候,都具有相同行為
Route::any('/', $callback);
註:事實上,不應該在 Route 中使用 Closure 作為路由行為定義,此處僅是為了示範才這麼做的
利用 {}
即可設定路由參數,並且在其後的 Callback 中讀取參數名稱
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/greetings/{name}', fn(string $name) => "Hello, $name");
若存取 /greetings/Jack
則可以看到 Hello, Jack
。
若在路由參數後加入 ?
代表可選參數,其後的 Callback 中可設定預設值
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/greetings/{name?}', fn(string $name = 'World') => "Hello, $name");
可以藉由 Regular Expression 去限制路由參數的型式
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
// 表示 id 僅能由 0~9 組成的數字串
Route::get('/user/{id}', $callback)
->where('id', '[0-9]+');
對於每個路由,建議都應該將其命名,不僅有助於管理也易於在使用時簡化。
可以利用 name()
進行命名
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/home', $callback)
->name('home');
Route::get('/greetings/{name?}', $callback)
->name('greetings');
// 使用方法
route('home'); // "http://127.0.0.1:8000/home"
route('greetings', ['name' => 'Jack']); // "http://127.0.0.1:8000/greetings/Jack"
藉由 group()
可將類似的路由組合在一起,並且享有類似的設定。
prefix()
可以讓路由具備相同的前綴:<?php
Route::prefix('admin')->group(function () {
Route::get('/', $callback);
Route::post('/', $callback);
// ...
});
name()
可以讓路由具備相同的路由前綴:<?php
Route::name('admin.')->grouop(function () {
Route::get('/admin', $callback);
Route::post('/admin', $callback);
// ...
});
Laravel 中,視圖功能類似於一個模板引擎(Template Engine),相較於直接使用 HTML 或 PHP 撰寫前端而言,它有著更多的小功能與可讀性上的改善。
預設而言,視圖應該都被放置於 resources/views
的資料夾下。
$ tree resources/views
resources/views
└── welcome.blade.php
0 directories, 1 file
視圖的副檔名為 .blade.php
,Blade 是一個 Laravel 社群所開發的模板引擎。
我們可以利用 Route::view()
去調用指定的視圖。
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::view('/', 'welcome');
如此一來,當用戶存取 /
時,便會使用 resources/views/welcome.blade.php
的視圖。
我們可以在 Route::view()
中設定變數,並在視圖中利用 {{}}
可以顯示變數。
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::view('/', 'welcome', ['name' => 'World']);
<!-- resources/views/welcome.blade.php -->
<h1>Hello, {{ $name }}</h1>
值得注意的是, {{}}
會自動調用 htmlspecialchars()
以避免 XSS 攻擊,所以可以在裡面放心輸出內容。
Blade 還有不少小功能,受限於篇幅的關係不一一做介紹,這部份可以參考官方文件的說明。
控制器一般是核心業務邏輯存放的地方之一,通常會在裡面橋接輸入與輸出,或是做一些運算。
可以利用以下指令建立控制器
$ php artisan make:controller [controller-name]
Controller created successfully.
新建立的控制器會位於 app/Http/Controllers
之中,檔案內容如下所示
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WelcomeController extends Controller
{
//
}
以 greetings
為例,建立一個會輸出 Hello World
的函式
<?php
// app/Http/Controllers/WelcomeController.php
// ...
class WelcomeController extends Controller
{
public function greetings()
{
return 'Hello World';
}
}
此時,在路由中可以呼叫 WelcomeController
中的 greetings()
<?php
// routes/web.php
use App\Http\Controllers\WelcomeController;
Route::get('/', [WelcomeController::class, 'greetings']);
又或是可以使用 __invoke
這個魔術方法去設計一個更簡潔的 Controller
<?php
// routes/web.php
use App\Http\Controllers\WelcomeController;
Route::get('/', WelcomeController::class);
// app/Http/Controllers/WelcomeController.php
// ...
class WelcomeController extends Controller
{
public function __invoke()
{
return 'Hello World';
}
}
有時候,路由會接收一些參數,我們可以在 Controller 中以函式參數的方式接收它。
<?php
// routes/web.php
use App\Http\Controllers\WelcomeController;
Route::get('/{name?}', WelcomeController::class);
// app/Http/Controllers/WelcomeController.php
// ...
class WelcomeController extends Controller
{
public function __invoke(string $name = 'World')
{
return "Hello, $name";
}
}
當然,Controller 並不僅是回傳 String 這麼簡單,它同時也可以回傳一個視圖。
<?php
class WelcomeController extends Controller
{
public function __invoke(string $name = 'World')
{
return view('welcome', ['name' => $name]);
}
}
或是可以回傳一個陣列,Laravel 會將其自動序列化(Serialize)為 JSON,這對於建立 API Server 非常好用
<?php
class WelcomeController extends Controller
{
public function __invoke(string $name = 'World')
{
return ['name' => $name];
}
}