鍍金池/ 教程/ PHP/ HTTP 控制器
Laravel Cashier
Eloquent ORM
HTTP 響應(yīng)
發(fā)行說明
擴(kuò)展包開發(fā)
HTTP 控制器
事件
擴(kuò)展框架
Contracts
開發(fā)
配置
表單驗(yàn)證
錯(cuò)誤與日志
Hashing
貢獻(xiàn)指南
郵件
Session
遷移與數(shù)據(jù)填充
查詢構(gòu)造器
Redis
升級向?qū)?/span>
概覽
緩存
服務(wù)提供者
Envoy 任務(wù)執(zhí)行器
隊(duì)列
單元測試
服務(wù)容器
文件系統(tǒng) / 云存儲
認(rèn)證
請求的生命周期
加密
模板
視圖 (View)
Laravel Homestead
Laravel 安裝指南
介紹
Command Bus
分頁
輔助方法
應(yīng)用程序結(jié)構(gòu)
HTTP 路由
HTTP 請求
基本用法
本地化
HTTP 中間件
結(jié)構(gòu)生成器
Facades
Laravel Elixir

HTTP 控制器

簡介 基礎(chǔ)控制器 控制器中間件 隱式控制器 RESTful 資源控制器 依賴注入和控制器 路由緩存

簡介

除了在單一的 routes.php 文件中定義所有的請求處理邏輯之外,你可能希望使用控制器類來組織此行為。控制器可將相關(guān)的 HTTP 請求處理邏輯組成一個(gè)類。控制器通常存放在 app/Http/Controllers 此目錄中。

基礎(chǔ)控制器

這里是一個(gè)基礎(chǔ)控制器類的例子:

<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class UserController extends Controller {

    /**
     * 顯示所給定的用戶個(gè)人數(shù)據(jù)。
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }

}

我們可以通過如下方式引導(dǎo)路由至對應(yīng)的控制器動作:

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

注意: 所有的控制器都應(yīng)該擴(kuò)展基礎(chǔ)控制器類。

控制器和命名空間

有一點(diǎn)非常重要,那就是我們無需指明完整的控制器命名空間,在類名稱中 App\Http\Controllers 之后的部分即可用于表示「根」命名空間。 RouteServiceProvider 默認(rèn)會在包含根控制器命名空間的路由群組中,加載 routes.php此文件。

若你要在 App\Http\Controllers 此目錄深層使用 PHP 命名空間以嵌套化或組織你的控制器,只要使用相對于 App\Http\Controllers 根命名空間的特定類名稱即可。因此,若你的控制器類全名為 App\Http\Controllers\Photos\AdminController,你可以像這樣注冊一個(gè)路由:

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

命名控制器路由

和閉包路由一樣,你也可以指定控制器路由的名稱。

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

指向控制器行為的 URL

要產(chǎn)生一個(gè)指向控制器行為的 URL,可使用 action 輔助方法。

$url = action('App\Http\Controllers\FooController@method');

若你想僅使用相對于控制器命名空間的類名稱中的一部分,來產(chǎn)生指向控制器行為的 URL,可用 URL 產(chǎn)生器注冊控制器的根命名空間。

URL::setRootControllerNamespace('App\Http\Controllers');

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

你可以使用 currentRouteAction 方法來獲取正在執(zhí)行的控制器行為名稱:

$action = Route::currentRouteAction();

控制器中間件

中間件 可在控制器路由中指定,例如:

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

此外,你也可以在控制器構(gòu)造器中指定中間件 :

class UserController extends Controller {

    /**
     * 建立一個(gè)新的 UserController 實(shí)例。
     */
    public function __construct()
    {
        $this->middleware('auth');

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

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

}

隱式控制器

Laravel 讓你能輕易地定義單一路由來處理控制器中的每一項(xiàng)行為。首先,用 Route::controller 方法定義一個(gè)路由:

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

Controller 方法接受兩個(gè)參數(shù)。第一個(gè)參數(shù)是控制器欲處理的 base URI,第二個(gè)是控制器的類名稱。接著只要在你的控制器中加入方法,并在名稱前加上它們所對應(yīng)的 HTTP 請求。

class UserController extends BaseController {

    public function getIndex()
    {
        //
    }

    public function postProfile()
    {
        //
    }

    public function anyLogin()
    {
        //
    }

}

index 方法會響應(yīng)控制器處理的根 URI ,在這個(gè)例子中是 users 。

如果你的控制器行為包含多個(gè)字詞,你可以在 URI 中使用「破折號」語法來訪問此行為。例如,下面這個(gè)在 UserController 中的控制器動作會響應(yīng) users/admin-profile 此一 URI :

public function getAdminProfile() {}

設(shè)定路由名字

如果你想“命名”一些控制器的路由,你可以給 controller 方法傳入第三個(gè)參數(shù):

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

RESTful 資源控制器

資源控制器可讓你無痛建立和資源相關(guān)的 RESTful 控制器。例如,你可能希望創(chuàng)建一個(gè)控制器,它可用來處理針對你的應(yīng)用程序所保存相片的 HTTP 請求。我們可以使用 make:controller Artisan 命令,快速創(chuàng)建這樣的控制器:

php artisan make:controller PhotoController

接著,我們注冊一個(gè)指向此控制器的資源路由:

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

此單一路由聲明創(chuàng)建了多個(gè)路由,用來處理各式各樣和相片資源相關(guān)的 RESTful 行為。同樣地,產(chǎn)生的控制器已有各種和這些行為綁定的方法,包含用來通知你它們處理了那些 URI 及動詞。

由資源控制器處理的行為

動詞 路徑 行為 路由名稱
GET /photo 索引 photo.index
GET /photo/create 創(chuàng)建 photo.create
POST /photo 保存 photo.store
GET /photo/{photo} 顯示 photo.show
GET /photo/{photo}/edit 編輯 photo.edit
PUT/PATCH /photo/{photo} 更新 photo.update
DELETE /photo/{photo} 刪除 photo.destroy

自定義資源路由

除此之外,你也可以指定讓路由僅處理一部分的行為:

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

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

所有的資源控制器行為默認(rèn)都有個(gè)路由名稱。然而你可在選項(xiàng)中傳遞一個(gè) names 數(shù)組來重載這些名稱:

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

處理嵌套資源控制器

在你的路由聲明中使用「點(diǎn)」號來「嵌套化」資源控制器:

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

此路由會注冊一個(gè)「嵌套的」資源,可透過像 photos/{photos}/comments/{comments} 這樣的 URL 來訪問。

class PhotoCommentController extends Controller {

    /**
     * 顯示指定照片的評論。
     *
     * @param  int  $photoId
     * @param  int  $commentId
     * @return Response
     */
    public function show($photoId, $commentId)
    {
        //
    }

}

在資源控制器中加入其他的路由

除了默認(rèn)的資源路由外,若你還需要在資源控制器中加入其他路由,應(yīng)該在調(diào)用 Route::resource 之前先定義它們:

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

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

依賴注入和控制器

構(gòu)造器注入

Laravel 服務(wù)容器 用于解析所有的 Laravel 控制器。因此,你可以在控制器所需要的構(gòu)造器中,對依賴作任何的類型限制。

<?php namespace App\Http\Controllers;

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

class UserController extends Controller {

    /**
     * 用戶保存庫實(shí)例。
     */
    protected $users;

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

}

當(dāng)然了,你也可以對任何的 Laravel contract 作類型限制。只要容器能解析它,你就可以對它作類型限制。

方法注入

除了建構(gòu)器注入外,你也可以對控制器方法的依賴作類型限制。例如,讓我們對某個(gè)方法的 Request 實(shí)例作類型限制:

<?php namespace App\Http\Controllers;

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

class UserController extends Controller {

    /**
     * 保存一個(gè)新的用戶。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }

}

如果你的控制器方法預(yù)期由路由參數(shù)取得輸入,只要在其他的依賴之后列出路由參數(shù)即可:

<?php namespace App\Http\Controllers;

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

class UserController extends Controller {

    /**
     * 保存一個(gè)新的用戶。
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }

}

注意: 方法注入和 模型綁定 是完全兼容的。容器可智能地判斷那些參數(shù)和模型相關(guān)以及那些參數(shù)應(yīng)該被注入。

路由緩存

若您的應(yīng)用只使用了控制器路由,你可利用 Laravel 的路由緩存。使用路由緩存,將大幅降低注冊應(yīng)用程序所有路由所需要的時(shí)間。某些情況下,路由注冊甚至可以快上 100 倍。要產(chǎn)生路由緩存,只要執(zhí)行 route:cache Artisan 命令:

php artisan route:cache

就是這樣!你的緩存路由文件將會被用來代替 app/Http/routes.php 此一文件。記住,若你增加了任何新的路由,你就 必須產(chǎn)生一個(gè)新的路由緩存。因此在應(yīng)用部署時(shí),你可能會希望只要執(zhí)行 route:cache 命令:

要移除路由緩存文件,但不希望產(chǎn)生新的緩存,可使用 route:clear 命令:

php artisan route:clear
上一篇:Eloquent ORM下一篇:升級向?qū)?/a>