iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
0
Modern Web

Laravel 8: For Beginners系列 第 4

Base Features (Part 1)

綱要

  • 路由(Routing)
  • 視圖(View)
  • 控器器(Controller)

路由(Routing)

路由表位於 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);
	// ...
});

視圖(View)

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 的一些小功能

Blade 還有不少小功能,受限於篇幅的關係不一一做介紹,這部份可以參考官方文件的說明。

控制器(Controller)

控制器一般是核心業務邏輯存放的地方之一,通常會在裡面橋接輸入與輸出,或是做一些運算。

建立控制器

可以利用以下指令建立控制器

$ 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 中以函式參數的方式接收它。

  • 這部份與在 Routing 中使用匿名函式的用法一致
<?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";
	}
}

回傳視圖或 JSON

當然,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];
	}
}

上一篇
Configuration
下一篇
Base Features (Part 2)
系列文
Laravel 8: For Beginners14

尚未有邦友留言

立即登入留言