鍍金池/ 教程/ PHP/ HTTP 控制器
門面
Laravel Homestead
安裝及配置
測(cè)試
HTTP 中間件
加密
升級(jí)指南
幫助函數(shù)
應(yīng)用目錄結(jié)構(gòu)
集合
新手入門指南-簡(jiǎn)單任務(wù)管理系統(tǒng)
任務(wù)調(diào)度
查詢構(gòu)建器
視圖
驗(yàn)證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊(duì)列
調(diào)整器
分頁
文件系統(tǒng)/云存儲(chǔ)
貢獻(xiàn)代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請(qǐng)求
Laravel Elixir
發(fā)行版本說明
Envoy 任務(wù)運(yùn)行器(SSH任務(wù))
序列化
Session
起步
帶用戶功能的任務(wù)管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務(wù)提供者
Blade 模板引擎
包開發(fā)
用戶認(rèn)證
Artisan 控制臺(tái)
HTTP 響應(yīng)
集合
服務(wù)容器
關(guān)聯(lián)關(guān)系
一次請(qǐng)求的生命周期
契約
Redis
錯(cuò)誤&日志

HTTP 控制器

1、簡(jiǎn)介

將所有的請(qǐng)求處理邏輯都放在單個(gè) routes.php 中肯定是不合理的,你也許還希望使用控制器類組織管理這些行為??刂破骺梢詫⑾嚓P(guān)的 HTTP 請(qǐng)求封裝到一個(gè)類中進(jìn)行處理。通常控制器存放在 app/Http/Controllers 目錄中。

2、基本控制器

下面是一個(gè)基本控制器類的例子。所有的 Laravel 控制器應(yīng)該繼承自 Laravel 自帶的控制器基類 Controller

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * 為指定用戶顯示詳情
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

我們可以像這樣定義指向該控制器動(dòng)作的路由:

Route::get('user/{id}', 'UserController@showProfile');

現(xiàn)在,如果一個(gè)請(qǐng)求匹配上面的路由 URI,UserControllershowProfile 方法就會(huì)被執(zhí)行。當(dāng)然,路由參數(shù)也會(huì)被傳遞給這個(gè)方法。

2.1 控制器&命名空間

你應(yīng)該注意到我們?cè)诙x控制器路由的時(shí)候沒有指定完整的控制器命名空間,而只是定義了 App\Http\Controllers 之后的部分。默認(rèn)情況下,RouteServiceProvider 將會(huì)在一個(gè)路由分組中載入 routes.php 文件,并且該路由分組指定定了分組中路由控制器所在的命名空間。

如果你在 App\Http\Controllers 目錄下選擇使用 PHP 命名空間嵌套或組織控制器,只需要使用相對(duì)于 App\Http\Controllers 命名空間的指定類名即可。因此,如果你的完整控制器類是 App\Http\Controllers\Photos\AdminController,你可以像這樣注冊(cè)路由:

Route::get('foo', 'Photos\AdminController@method');

2.2 命名控制器路由

和閉包路由一樣,可以指定控制器路由的名字:

Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);

設(shè)置好控制器路由后,就可以使用幫助函數(shù) action 很方便地為控制器動(dòng)作生成對(duì)應(yīng)的 URL:

$url = action('FooController@method');

你還可以使用幫助函數(shù) route 來為已命名的控制器路由生成對(duì)應(yīng)的 URL:

$url = route('name');

3、控制器中間件

中間件可以像這樣分配給控制器路由:

Route::get('profile', [
    'middleware' => 'auth',
    'uses' => 'UserController@showProfile'
]);

但是,將中間件放在控制器構(gòu)造函數(shù)中更方便,在控制器的構(gòu)造函數(shù)中使用 middleware 方法你可以很輕松的分配中間件給該控制器。你甚至可以限定該中間件應(yīng)用到該控制器類的指定方法:

class UserController extends Controller
{
    /**
     * 實(shí)例化一個(gè)新的 UserController 實(shí)例
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log', ['only' => ['fooAction', 'barAction']]);

        $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
    }
}

4、RESTful 資源控制器

Laravel 的資源控制器使得構(gòu)建圍繞資源的 RESTful 控制器變得毫無痛苦,例如,你可能想要在應(yīng)用中創(chuàng)建一個(gè)控制器,用于處理關(guān)于圖片存儲(chǔ)的 HTTP 請(qǐng)求,使用 Artisan 命令 make:controller,我們可以快速創(chuàng)建這樣的控制器:

php artisan make:controller PhotoController

該 Artisan 命令將會(huì)生成一個(gè)控制器文件 app/Http/Controllers/PhotoController.php,這個(gè)控制器包含了每一個(gè)資源操作對(duì)應(yīng)的方法。 接下來,可以為該控制器注冊(cè)一個(gè)資源路由:

Route::resource('photo', 'PhotoController');

這個(gè)路由聲明包含了處理圖片資源 RESTful 動(dòng)作的多個(gè)路由,相應(yīng)地,Artisan 生成的控制器也已經(jīng)為這些動(dòng)作設(shè)置了對(duì)應(yīng)的處理方法。

4.1 資源控制器處理的動(dòng)作

http://wiki.jikexueyuan.com/project/laravel-5.1/images/1.png" alt="" />

4.2 只定義部分資源路由

聲明資源路由時(shí)可以指定該路由處理的動(dòng)作子集:

Route::resource('photo', 'PhotoController',
                ['only' => ['index', 'show']]);

Route::resource('photo', 'PhotoController',
                ['except' => ['create', 'store', 'update', 'destroy']]);

4.3 命名資源路由

默認(rèn)情況下,所有資源控制器動(dòng)作都有一個(gè)路由名稱,然而,我們可以通過傳入 names 數(shù)組來覆蓋這些默認(rèn)的名字:

Route::resource('photo', 'PhotoController',
                ['names' => ['create' => 'photo.build']]);

4.4 嵌套資源

有時(shí)候我們需要定義路由到“嵌套”資源。例如,一個(gè)圖片資源可能擁有多條“評(píng)論”,要“嵌套”資源控制器,在路由聲明中使用“.”號(hào)即可:

Route::resource('photos.comments', 'PhotoCommentController');

該路由將注冊(cè)一個(gè)嵌套的資源,使用 URL 訪問方式如下: photos/{photos}/comments/{comments}.

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class PhotoCommentController extends Controller
{
    /**
     * 顯示指定照片評(píng)論
     *
     * @param  int  $photoId
     * @param  int  $commentId
     * @return Response
     * @translator http://laravelacademy.org
     */
    public function show($photoId, $commentId)
    {
        //
    }
}

4.5 補(bǔ)充資源控制器

如果有必要在默認(rèn)資源路由之外添加額外的路由到資源控制器,應(yīng)該在調(diào)用 Route::resource 之前定義這些路由;否則,通過 resource 方法定義的路由可能無意中優(yōu)先于補(bǔ)充的額外路由:

Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');

擴(kuò)展閱讀:實(shí)例教程——?jiǎng)?chuàng)建 RESTFul 風(fēng)格控制器實(shí)現(xiàn)文章增刪改查

5、隱式控制器

Laravel 允許你只定義一個(gè)路由即可訪問控制器類中的所有動(dòng)作,首先,使用 Route::controller 方法定義一個(gè)路由,該 controller 方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是控制器處理的 baseURI,第二個(gè)參數(shù)是控制器的類名:

Route::controller('users', 'UserController');

接下來,添加方法到控制器,方法名應(yīng)該以 HTTP 請(qǐng)求方法開頭:

<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
    /**
     * 響應(yīng) GET /users 請(qǐng)求
     */
    public function getIndex()
    {
        //
    }

    /**
     * 響應(yīng) GET /users/show/1 請(qǐng)求
     */
    public function getShow($id)
    {
        //
    }

    /**
     * 響應(yīng) GET /users/admin-profile 請(qǐng)求
     */
    public function getAdminProfile()
    {
        //
    }

    /**
     * 響應(yīng) POST /users/profile 請(qǐng)求
     */
    public function postProfile()
    {
        //
    }
}

在上例中可以看到,getIndex 方法將會(huì)在訪問控制器處理的默認(rèn) URI——users 時(shí)被調(diào)用。

5.1 分配路由名稱

如果你想要命名該控制器中的一些路由,可以將一個(gè)名稱數(shù)組作為第三個(gè)參數(shù)傳遞到該 controller 方法:

Route::controller('users', 'UserController', [
    'getShow' => 'user.show',
]);

6、依賴注入 & 控制器

6.1 構(gòu)造函數(shù)注入

Laravel 使用服務(wù)容器解析所有的 Laravel 控制器,因此,可以在控制器的構(gòu)造函數(shù)中類型聲明任何依賴,這些依賴會(huì)被自動(dòng)解析并注入到控制器實(shí)例中:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * 創(chuàng)建新的控制器實(shí)例
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }
}

當(dāng)然,你還可以類型提示任何 Laravel 契約,如果容器可以解析,就可以進(jìn)行類型提示。

6.2 方法注入

除了構(gòu)造函數(shù)注入之外,還可以在控制器的動(dòng)作方法中進(jìn)行依賴的類型提示,例如,我們可以在某個(gè)方法中類型提示 Illuminate\Http\Request 實(shí)例:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class UserController extends Controller
{
    /**
     * 存儲(chǔ)新用戶
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }
}

如果控制器方法期望輸入路由參數(shù),只需要將路由參數(shù)放到其他依賴之后,例如,如果你的路由定義如下:

Route::put('user/{id}', 'UserController@update');

你需要通過定義控制器方法如下所示來類型提示 Illuminate\Http\Request 并訪問路由參數(shù) id

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class UserController extends Controller
{
    /**
     * 更新指定用戶
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     * @translator http://laravelacademy.org
     */
    public function update(Request $request, $id)
    {
        //
    }
}

7、路由緩存

如果你的應(yīng)用完全基于路由使用控制器,可以使用 Laravel 的路由緩存,使用路由緩存將會(huì)極大減少注冊(cè)所有應(yīng)用路由所花費(fèi)的時(shí)間開銷,在某些案例中,路由注冊(cè)速度甚至能提高 100 倍!想要生成路由緩存,只需執(zhí)行 Artisan 命令 route:cache:

php artisan route:cache

就這么簡(jiǎn)單!你的緩存路由文件現(xiàn)在取代 app/Http/routes.php 文件被使用,記住,如果你添加新的路由需要重新生成路由緩存。因此,只有在項(xiàng)目開發(fā)階段你才會(huì)運(yùn)行 route:cache 命令。 想要移除緩存路由文件,使用 route:clear 命令即可:

php artisan route:clear
上一篇:驗(yàn)證