iT邦幫忙

1

Laravel 技術筆記 (二)【Controllers 控制器】

  • 分享至 

  • xImage
  •  

介紹

觀看本篇前,建議先了解何謂 MVC 模式,簡單說控制器的作用就像是交通警察,應用程式在接收 HTTP 請求後,負責將正確的資料從資料庫或其他儲存機制取出並回傳給使用者,回傳的內容可以是一個 view 檔案或一則簡單的訊息端看開發者如何定義,還有就是不建議將應用程式的所有邏輯處理都寫進控制器 ,比較好的作法是讓控制器只負責解析來自 HTTP 請求的意圖,並引導應用程式的其餘部分去處理這些邏輯。


新增控制器

Laravel 的控制器檔案都放在 app/Http/Controllers 目錄中,並且 artisan 也提供方便的語法來新增:

$ php artisan make:controller DemoController

上述語法會產生一名稱為 DemoController.php 的檔案如下,筆者在這邊自行定義了一個簡單的方法 index:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DemoController extends Controller
{
    public function index()
    {
        return 'Hello, World !!';
    }
}

接著如同上一篇的做法,我們將此控制器掛上一個路由:

<?php

use Illuminate\Support\Facades\Route;

Route::get('/index', 'App\Http\Controllers\DemoController@index');

最後造訪「/index」即可看到 Hello, World !! 訊息。


單一動作控制器

若你撰寫的控制器只打算匹配一個路由,你可以不用為了替方法想名稱而煩惱,只需將你的方法命名為 __invoke:

<?php
 
namespace App\Http\Controllers;

use Illuminate\Http\Request;
 
class DemoController extends Controller
{
    public function __invoke()
    {
        return 'Hello, World !!';
    }
}

這時路由定義可以不標註方法的名稱,Laravel 會將整個類別當做函式呼叫:

<?php

use Illuminate\Support\Facades\Route;

Route::get('/index', 'App\Http\Controllers\DemoController');

控制器中介層

除了在路由中使用中介層外,控制器也可以在建構式中使用中介層以及套用在指定的方法上:

<?php
 
namespace App\Http\Controllers;

use Illuminate\Http\Request;
 
class DemoController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('log')->only('index');
        $this->middleware('subscribed')->except('store');
    }
}

資源控制器

當你為了一項「資源」的 CRUD 處理而撰寫控制器時,Laravel 提供一個很好的方法讓你一次綁定整個資源,這邊以資源「照片」做為示範:

$ php artisan make:controller PhotoController --resource

這時我們會發現檔案內已經預先定義好幾個方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PhotoController extends Controller
{
    public function index()
    {
        //
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        //
    }

    public function show($id)
    {
        //
    }

    public function edit($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        //
    }

    public function destroy($id)
    {
        //
    }
}

接著我們定義一個路由來指向 PhotoController 這個控制器:

<?php

use Illuminate\Support\Facades\Route;

Route::resource('/photos', 'App\Http\Controllers\PhotoController');

最後我們輸入以下 artisan 指令列出可用路由的清單:

$ php artisan route:list

https://ithelp.ithome.com.tw/upload/images/20220301/20135794Nm11XpuHgI.jpg
可以發現有 7 組 Laravel 幫我們設定好的路由完整匹配 PhotoController 控制器內的 7 個方法,這樣便可以省下命名與重複定義路由的功夫。
有需要的話,還可以指定要執行的路由,而不是默認值的全部:

<?php

use Illuminate\Support\Facades\Route;

/* 只會執行匹配控制器中 index、show 兩個方法的路由 */
Route::resource('photos', 'App\Http\Controllers\PhotoController')->only([
    'index', 'show'
]);
/* index、show 兩個方法的路由不執行,其他的都會執行 */
Route::resource('photos', 'App\Http\Controllers\PhotoController')->except([
    'index', 'show'
]);

API 資源控制器

在為你的 API 定義資源控制器所匹配的路由時,可以使用 apiResource() 來排除 create、edit 這兩組路由:

<?php

use Illuminate\Support\Facades\Route;

Route::apiResource('photos', 'App\Http\Controllers\PhotoController');

可以透過將陣列傳遞給 apiResource() 達到一次定義多組資源控制器:

<?php

use Illuminate\Support\Facades\Route;

Route::apiResources([
    'photos' => 'App\Http\Controllers\PhotoController',
    'resources' => 'App\Http\Controllers\ResourceController',
]);

而要快速新增排除 create、edit 方法的 API 資源控制器時,artisan 也有提供方便的指令:

php artisan make:controller PhotoController --api

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言