HTTP 控制器

简介

除了在单一的 routes.php 文件中定义所有的请求处理逻辑之外,你可能希望使用控制器类来组织此行为。控制器可将相关的 HTTP 请求处理逻辑组成一个类。控制器通常存放在app/Http/Controllers 目录中。

#基础控制器

这里是一个基础控制器类的例子:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}

我们可以通过如下方式引导路由至对应的控制器动作:

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

注意: 所有的控制器都应该扩展基础控制器类。

现在,当一个请求地址匹配特定路由时,UserController 类中的 showProfile 方法就会得到执行, 当然,路由的参数也会传递到方法中。

 

控制器和命名空间

有一点非常重要,那就是我们无需指明完整的控制器命名空间,在类名称中 App\Http\Controllers之后的部分即可用于表示「根」命名空间。 RouteServiceProvider 默认会在包含根控制器命名空间的路由群组中,加载 routes.php 文件。

若你要在 App\Http\Controllers 此目录深层使用 PHP 命名空间以嵌套化或组织你的控制器,只要使用相对于 App\Http\Controllers 根命名空间的特定类名称即可。因此,若你的控制器类全名为App\Http\Controllers\Photos\AdminController,你可以像这样注册一个路由:

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

命名控制器路由

和闭包路由一样,你也可以指定控制器路由的名称。

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

指向控制器行为的 URL

Once you have assigned a name to the controller route, you can easily generate URLs to the action. To generate a URL to a controller action, use the action helper method. Again, we only need to specify the part of the controller class name that comes after the base App\Http\Controllersnamespace:

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

也可以用 route 辅助方法来产生命名控制器路由的URL

$url = route('name');

#控制器中间件

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

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

然而,更方便的是在控制器构造器中指定中间件, 在构造器中使用middleware 方法,你就可以给控制器指定中间件,你还可以限制中间件使用于控制器类的特定方法。

class UserController extends Controller
{
/**
* Instantiate a new UserController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth'); $this->middleware('log', ['only' => ['fooAction', 'barAction']]); $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
}
 

#RESTful 资源控制器

资源控制器可让你无痛建立和资源相关的 RESTful 控制器。例如,你可能希望创建一个控制器,它可用来处理针对你的应用程序所保存相片的 HTTP 请求。我们可以使用 make:controller Artisan 命令,快速创建这样的控制器:

php artisan make:controller PhotoController

这个Artisan命令会在 app/Http/Controllers/PhotoController.php 生成控制器文件, 这个控制器会对每个资源操作类型产生一个方法。 接着,我们注册一个指向此控制器的资源路由:

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

此单一路由声明创建了多个路由,用来处理各式各样和相片资源相关的 RESTful 行为。同样地,产生的控制器已有各种和这些行为绑定的方法,包含了提醒你它们处理了那些 URI 及动词的说明注释。

 
 

由资源控制器处理的行为

Verb Path Action Route Name
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
 
 

部分资源路由

当声明资源路由时,你也可以指定动作actions的一个子集来处理路由:

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

命名资源路由

所有的资源控制器行为默认都有个路由名称。然而你可在选项中传递一个 names 数组来重载这些名称:

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

处理嵌套资源控制器

在你的路由声明中使用「点」号来「嵌套化」资源控制器:

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

此路由会注册一个「嵌套的」资源,可透过像 photos/{photos}/comments/{comments} 这样的 URL 来访问。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class PhotoCommentController extends Controller
{
/**
* Show the specified photo comment.
*
* @param int $photoId
* @param int $commentId
* @return Response
*/
public function show($photoId, $commentId)
{
//
}
}

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

If it becomes necessary to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes:

在资源控制器之外添加额外路由已成为必要, 你应该在资源控制器之前就定义那些路由, 否则,资源方法定义的路由会不小心优先于附加的路由。

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

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

 

#隐式控制器

Laravel 让你能轻易地定义单一路由来处理控制器中的每一项行为。首先,用 Route::controller 方法定义一个路由,Controller 方法接受两个参数。第一个参数是控制器欲处理的 base URI,第二个是控制器的类名称。接着只要在你的控制器中加入方法,并在名称前加上它们所对应的 HTTP 请求。

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

<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
/**
* Responds to requests to GET /users
*/
public function getIndex()
{
//
} /**
* Responds to requests to GET /users/show/1
*/
public function getShow($id)
{
//
} /**
* Responds to requests to GET /users/admin-profile
*/
public function getAdminProfile()
{
//
} /**
* Responds to requests to POST /users/profile
*/
public function postProfile()
{
//
}
}

index 方法会响应控制器处理的根 URI ,在这个例子中是 users

如果你的控制器行为包含多个字词,你可以在 URI 中使用「破折号」语法来访问此行为。例如,下面这个在 UserController 中的控制器动作会响应 users/admin-profile 此一 URI :

public function getAdminProfile() {}

设定路由名字

如果你想“命名”一些控制器的路由,你可以给 controller 方法传入第三个参数:

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

 

依赖注入和控制器

构造器注入

Laravel 服务容器 用于解析所有的 Laravel 控制器。因此,你可以在控制器所需要的构造器中,对依赖作任何的类型限制。依赖会自动绑定,并注入到controller实例中。

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Repositories\UserRepository; class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users; /**
* Create a new controller instance.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}

当然了,你也可以对任何的 Laravel contract 作类型限制。只要容器能解析它,你就可以对它作类型限制。

 

方法注入

除了建构器注入外,你也可以对控制器方法的依赖作类型限制。例如,让我们对某个方法的Request 实例作类型限制:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller; class UserController extends Controller
{
/**
* Store a new user.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$name = $request->input('name'); //
}
}

如果你的控制器方法预期由路由参数取得输入,只要在其他的依赖之后列出路由参数即可:

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

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller; class UserController extends Controller
{
/**
* Update the specified user.
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}

注意: 方法注入和 模型绑定 是完全兼容的。容器可智能地判断那些参数和模型相关以及那些参数应该被注入。他妈也神奇了。

路由缓存

若您的应用只使用了控制器路由,你可利用 Laravel 的路由缓存。使用路由缓存,将大幅降低注册应用程序所有路由所需要的时间。某些情况下,路由注册甚至可以快上 100 倍。要产生路由缓存,只要执行 route:cache Artisan 命令:

php artisan route:cache

就是这样!你的缓存路由文件将会被用来代替 app/Http/routes.php 此一文件。记住,若你增加了任何新的路由,你就 必须产生一个新的路由缓存。因此在应用部署时,你可能会希望只要执行route:cache 命令:

要移除路由缓存文件,但不希望产生新的缓存,可使用 route:clear 命令:

php artisan route:clear

Laravel5.1学习笔记4 控制器的更多相关文章

  1. Swoft2.x 小白学习笔记 (一) ---控制器

    Swoft通过官方文档进行学习,这里不做介绍,直接上手. 涉及到Swoft方面:(配置.注意的坑) 1.控制器(路由.验证器.中间件) 2.mysql  (Model使用).Redis配置及通用池 3 ...

  2. ThinkPHP 学习笔记 ( 二 ) 控制器 ( Controller )

    /** * ThinkPHP version 3.1.3 * 部署方式:应用部署 * 文内的 http://localhost/ 由实际主机地址代替 */ 入口文件 index.php: <?p ...

  3. IOS 学习笔记 2015-04-15 控制器数据反向传值

    // // FirstViewController.h // 控制器数据传递 // // Created by wangtouwang on 15/4/15. // Copyright (c) 201 ...

  4. STM32学习笔记——DMA控制器(向原子哥学习)

    一.DMA简介 DMA,全称为:Direct Memory Access,即直接存储器访问,DMA 用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输.当 CPU 初始化这个传输动作,传输 ...

  5. ASP.NET MVC5 学习笔记-1 控制器、路由、返回类型、选择器、过滤器

    [TOC] 1. Action 1.1 新建项目 新建项目->Web->Asp.net Web应用程序,选择MVC,选择添加测试. 在解决方案上右键,选择"管理NuGet程序包& ...

  6. Symfony2 学习笔记之控制器

    一个controller是你创建的一个PHP函数,它接收HTTP请求(request)并创建和返回一个HTTP回复(Response).回复对象(Response)可以是一个HTML页面,一个XML文 ...

  7. laravel5.4学习笔记

    1.安装laravel可以直接用composer安装,然后用laravel new xxx来新建项目 服务器上安装了composer(php包管理工具)以后, composer global requ ...

  8. Laravel5.1学习笔记19 EloquentORM 入门

    Eloquent:入门 简介 定义模型(model) Eloquent 模型规范 取出多个模型 取出单个模型 / 集合 取出集合 插入更新模型  基本插入 基本更新 大批量赋值 删除模型 软删除 查询 ...

  9. Laravel5.1学习笔记18 数据库4 数据填充

    简介 编写数据填充类 使用模型工厂类 调用额外填充类 执行填充 #简介 Laravel includes a simple method of seeding your database with t ...

随机推荐

  1. eas之列表界面写脚本时如何写sql

    var easNames = JavaImporter();easNames.importPackage(Packages.com.kingdee.bos.dao.query);with(easNam ...

  2. 《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序

    题目: 每个学生的信息卡片包括学号.姓名和成绩三项.定义存储学生信息的单向链表的结点类型:编写函 数,由文件依次读入 n(n≥0)个学生的信息,创建一个用于管理学生信息的单向链表:编写函数,对 该链表 ...

  3. PAT 1102 Invert a Binary Tree

    The following is from Max Howell @twitter: Google: 90% of our engineers use the software you wrote ( ...

  4. 创建Spark执行环境SparkEnv

    SparkDriver 用于提交用户的应用程序, 一.SparkConf 负责SparkContext的配置参数加载, 主要通过ConcurrentHashMap来维护各种`spark.*`的配置属性 ...

  5. PatentTips - Mechanisms for strong atomicity in a transactional memory system

    BACKGROUND Advances in semi-conductor processing and logic design have permitted an increase in the ...

  6. wait-notify模型面试题

    一道面试题: 启动两个线程, 一个输出 1,3,5,7-99, 另一个输出 2,4,6,8-100 最后 STDOUT 中按序输出 1,2,3,4,5-100 错误实现1: public class ...

  7. Clojure:将两个list合并成一个map

    假设我们有两个list,分别是: (def a [“one” “two” “three”]) (def b [1 2 3]) 我们要把它们合为一个键值对应的map,做法很简单: 1. 先将a和b合为一 ...

  8. 熊猫猪新系统測试之中的一个:Windows 10 技术预览版

    话说本猫不用windows非常多年了呀! 只是看到微软最新的Windows10还是手痒了.想安装体验一把. 于是第一时间下载,并做成usb引导安装镜像,在08年的老台式机上安装尝鲜鸟.下载ISO和安装 ...

  9. VBS 控制语句

    1.if...then...end if if [条件] then [执行语句] end if 可以嵌套 多个if if [条件] then [执行语句] else if [条件] then [执行语 ...

  10. P3387 【模板】缩点 tarjan

    虽说是模板题,但是竟然中间有dp的部分...先tarjan缩点,重新建图.然后记忆化搜索,搜索dag中的最小环. 题干: 题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值, ...