Laravel 技术笔记 (二)【Controllers 控制器】

介绍

观看本篇前,建议先了解何谓 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

<<:  网路的小技巧-3

>>:  【HTML】标记?标签?HTML元素?

day1 只要有钱,什麽缺都做 (雷)系统工程师

来部落格看图文并茂文章 补觉鸣诗 乞丐 当时刚退伍我就跟乞丐没两样,大学努力存的钱,都在当兵时消失殆...

[Day9] ORM Injection

前言 :你有听过SQL Injection吗? :有阿 :那你知道怎麽防范吗? :参数化查询、ORM...

Day20 让电脑透过数据机和有线、无线网路传递讯息

上一回讲的是透过数据机连结各种电脑周边 今天来分享数据机更强大的功能,传递讯息 可以先查询 mode...

你要的是Entity Framework吗?

很多初学Entity Framework( Core)(以下简称EF)的新手,刚开始使用EF时都会有...

比起懂最新的知识,工程师更应该懂这些.......

有些公司永远在徵人(人员一直在流动),实际去应徵过後,会深刻理解到为什麽。 前几天提到GitHub时...