laravel 基礎(chǔ)教程 —— 控制器

HTTP 控制器

簡(jiǎn)介

控制器允許你將相應(yīng)的路由業(yè)務(wù)邏輯封裝在控制器類(lèi)中進(jìn)行有效的管理,這樣你不必將所有的路由邏輯集中到routes.php文件中,導(dǎo)致代碼的臃腫與難以維護(hù)。
所有的控制器類(lèi)都被存儲(chǔ)在app/Http/Controllers目錄中.

基本控制器

一個(gè)基本的控制器應(yīng)該繼承自App\Http\Controllers\Controller控制器類(lèi):

<?php

namespace App\Http\Controllers;

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

class UserController extends Controller {
  public function showProfile($id) {
    return view('user.profile', ['user' => User::findOrFail($id)]);
  }
}

我們可以通過(guò)下面的方式把控制器的行為分配到路由:

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

一旦將控制器的行為分配到路由之后,每次客戶(hù)端請(qǐng)求該路由,都會(huì)觸發(fā)控制器的行為。這里即客戶(hù)端每次請(qǐng)求user/{id}路由,showProfile方法都會(huì)被執(zhí)行,路由中的參數(shù)也會(huì)被直接傳遞到該方法中.

控制器 & 命名空間

你應(yīng)該知道我們?cè)诙x控制器路由時(shí)是不需要指定控制器的命名空間的,而只需要指定到類(lèi)名就可以了,這是因?yàn)樵?code>RouteServiceProvider文件中自動(dòng)加載的routes.php文件已經(jīng)被指定了路由組的根命名空間App\Http\Controllers;

如果你想在App\Http\Controllers目錄下使用php命名空間來(lái)嵌套或組織控制器,那么你只需要簡(jiǎn)單的指定相對(duì)于App\Http\Controllers部分的類(lèi)名就可以了。所以如果你的控制器的全部類(lèi)名為App\Http\Controllers\Photos\AdminController,那么你就可以這樣來(lái)定義控制器路由:

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

命名控制器路由

就像定義命名路由一樣,我們也可以給一個(gè)控制器路由命名:

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

一旦你為一個(gè)路由進(jìn)行了命名, 那么你就可以通過(guò)route幫助方法去快速的生成被命名路由的資源表述地址:

$url = route('name');

控制器中間件

中間件可以這樣被分配到控制器路由中:

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

當(dāng)然你也可以在控制器類(lèi)中直接使用middleware方法來(lái)進(jìn)行中間件的分配,你也可以只允許類(lèi)中的某些行為受到指定中間件的約束:

class UserController extends Controller {
  public function __construct() {
    $this->middleware('auth');

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

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

RESTful 資源控制器

資源控制器可以使你快速的構(gòu)建RESTful型的控制器。你可以使用artisan命令來(lái)快速的創(chuàng)建:

php artisan make:controller PhotoController --resource

該命令會(huì)生成app\Http\Controllers\PhotoController.php文件,資源控制器中將包含每個(gè)可用的資源操作相應(yīng)的方法.

你可以通過(guò)下面的方式來(lái)進(jìn)行資源路由的注冊(cè):

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

這一個(gè)簡(jiǎn)單的聲明會(huì)創(chuàng)造多條路由用來(lái)處理RESTful式的請(qǐng)求.相應(yīng)的通過(guò)命令生成的資源型控制器也為這些請(qǐng)求設(shè)置了對(duì)應(yīng)的處理方法.

資源控制器所處理的行為

請(qǐng)求方式 路由地址 控制器行為 路由命名
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy

部分資源路由

有時(shí)候你可能并不想控制器處理全部的請(qǐng)求方式,那么你可以這么做:

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

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

命名資源路由

默認(rèn)的,所有的資源控制器行為都被進(jìn)行了相應(yīng)的路由命名,你可以通過(guò)names參數(shù)來(lái)進(jìn)行重命名:

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

命名資源路由參數(shù)

默認(rèn)的,資源路由的路由參數(shù)都被命名為相應(yīng)的資源名稱(chēng),你可以用過(guò)parameters參數(shù)來(lái)進(jìn)行重命名:

Route::resource('user', 'AdminUserController', ['parameters' => [
  'user' => 'admin_user'
]]);

// /user/{admin_user}

有時(shí)候你可能希望資源路由的路由參數(shù)并不需要像默認(rèn)的資源名稱(chēng)一樣采取復(fù)數(shù)的形式,那么你可以通過(guò)傳遞parameters的選項(xiàng)設(shè)置為singular:

Route::resource('users.photos', 'PhotoController', [
  'parameters' => 'singular'
]);

// /users/{user}/photos/{photo}

另外,你也可以全局設(shè)置你的資源路由參數(shù)為單數(shù)形式或者全局進(jìn)行資源路由參數(shù)的命名映射:

Route::singularResourceParameters();

Route::resourceParameters([
  'user' => 'person',
  'photo' => 'image'
])

當(dāng)你對(duì)資源路由參數(shù)進(jìn)行定制時(shí),你應(yīng)該清楚的知道命名的順序優(yōu)先級(jí):

  1. 參數(shù)被直接的傳遞給Route::resource
  2. 通過(guò) Router::resourceParameters 進(jìn)行全局參數(shù)映射
  3. 通過(guò)parameters數(shù)組選項(xiàng)傳遞給Route::resource 或者 通過(guò) Route::singularResoureParameters 進(jìn)行單數(shù)形式參數(shù)設(shè)置
  4. 默認(rèn)行為

資源控制器中意外的行為

如果你必須在資源控制器中添加額外的行為去注冊(cè)相應(yīng)的路由,那么你一定要在使用Route::resource之前進(jìn)行注冊(cè),否則該行為很可能會(huì)被資源控制器意外的覆蓋掉.

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

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

依賴(lài)注入 & 控制器

構(gòu)造器注入

laravel的服務(wù)容器支持所有的laravel控制器的解析。由于這個(gè)原因,所以你可以在控制器的構(gòu)造函數(shù)中添加你所需要依賴(lài)的相應(yīng)類(lèi)型提示,這些依賴(lài)會(huì)被自動(dòng)的解析并注入進(jìn)控制器實(shí)例.

<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller {
  protected $users;

  public function __construct(UserRepository $users) {
    $this->users = $users;
  }
}

當(dāng)然,你也被允許添加一些laravel contract的類(lèi)型提示,只要服務(wù)容器能夠正確的解析,你都可以被允許添加。

方法注入

除了在構(gòu)造函數(shù)中進(jìn)行依賴(lài)注入,你也可以在控制器的行為方法中進(jìn)行依賴(lài)注入,比如,將Illuminate\Http\Reqeust實(shí)例注入到控制器的store方法中:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller {
  public function store (Request $request) {
    $name = $request->input('name');
  }
}

如果你的控制器方法也接收從路由傳遞過(guò)來(lái)的參數(shù),那么他們會(huì)在其它依賴(lài)解析完畢之后被傳遞,比如你的路由是這么定義的:

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

那么你可以這么修正你的控制器行為,來(lái)進(jìn)行參數(shù)的接收:

<?php

namespace App\Http\controllers;

use Illuminate\Http\Request;

class UserController extends Controller {
  public function update (Request $request, $id) {
    // 
  }
}

緩存路由

注意:緩存路由不支持閉包函數(shù)定義的路由,如果你想使你的路由被緩存,那么你應(yīng)該使用控制器來(lái)管理你的路由.

如果你所有的路由都是基于控制器的路由,那么你應(yīng)該使用laravel推薦的緩存路由,你可以簡(jiǎn)單的通過(guò)artisan命令來(lái)緩存所有路由注冊(cè)到同一個(gè)文件里,它會(huì)替代routes.php文件被解析,使用這種緩存注冊(cè)路由的方式在某些情況下注冊(cè)路由的時(shí)間將被大大的減少,從而提高了應(yīng)用的響應(yīng)速度。
但是每次添加新的路由或者刪除路由時(shí),為了使路由生效,你需要重新生成一次緩存路由:

php artisan route:cache

你可以通過(guò)下面的方式去刪除路由緩存:

php artisan route:clear
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評(píng)論 19 139
  • 0.1配置1.模板繼承2.控制器3.git4.支付寶支付的流程5.路由6.中間件7.請(qǐng)求8.laravel 學(xué)習(xí)筆...
    云龍789閱讀 919評(píng)論 0 5
  • 介紹 不要把所有處理請(qǐng)求的邏輯都放到一個(gè)單獨(dú)的 routes.php 文件里,我們可以使用控制器去組織這些行為。C...
    伊Summer閱讀 899評(píng)論 0 1
  • 路由 路由(routing)就是通過(guò)互聯(lián)的網(wǎng)絡(luò)把信息從源地址傳輸?shù)侥康牡刂返幕顒?dòng)。路由發(fā)生在OSI網(wǎng)絡(luò)參考模型中的...
    Dearmadman閱讀 2,967評(píng)論 2 9
  • 昨天工作到凌晨3點(diǎn)多,我看問(wèn)題解決了我就先撤了,沒(méi)想到今天起來(lái)發(fā)現(xiàn)昨天有很多人又通宵了。早晨去把問(wèn)題處理后,得知項(xiàng)...
    任雨點(diǎn)閱讀 178評(píng)論 0 0

友情鏈接更多精彩內(nèi)容