控制器(Controller)

本节包含以下方面的内容

  • 基本概念
  • 路由
    • 默认路由
  • 动作的参数
    • 在动作中定义参数
    • 从请求(request)中获取参数
  • 独立动作
  • 动作过滤器(Action Filters)
  • 捕获所有的请求
  • 自定义响应类

控制器(Controller)是应用程序中最关键的部分之一,它决定了如何处理传递进来的请求(Request),以及生成相应的响应(Response)。
大部分的控制器都会处理一个Http的请求,然后返回Html或者Json或者Xml格式的数据作为响应。

1、基本概念

控制器文件一般在应用程序的controllers目录下面,文件命名规则为XXXController.php,其中XXX可以为任意的名称,后面的Controller是固定格式,不能少一个单词。

一个基本的控制器的定义要从yii\web\Controller继承,如

namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex()
{
// will render view from "views/site/index.php"
return $this->render('index');
}
public function actionTest()
{
// will just print "test" to the browser
return 'test';
}
}

一般来说控制器里面定义的动作都是 actionSomething格式的公共的方法。输出的数据可以是一个字符串或者yii\web\Response的实例。

动作输出的结果将会由 response组件处理并转换成不同的数据格式如JSON等。默认情况下是没有对动作的执行结果进行处理的。

2、路由

每个控制器里面的动作都有一个相对应的路由,在上面的例子中actionIndex有一个对应的site/index路由,actionTest对应的路由是site/test。在这个路由中site为控制器的id,test为动作的id。

一般情况下可以通过这个格式的URL来访问控制器和动作。http://example.com/?r=controller/action。当然你可以完全自定义url的格式(URL Management.)。

如果控制器是在一个模块里面,那么对应的路由格式为module/controller/action。

控制器还可以存在于应用程序或者模块的控制器目录下面的子目录里。这种路由的格式前面就需要加上相应的目录名称。例如在controllers/admin下面有个UserController,那么动作actionIndex相应的路由为admin/user/index。admin/user为控制器的Id.

如果模块或者控制器或者动作都没有找到,Yii将会返回一个"not found" 页面,并且返回的Http代码为404。

注意:
如果模块名称或者控制器名称或者动作名称是用的骆驼格式的命名写法,那么路由里面的每个大写单词之间都要用“-”来连接。如
DateTimeController::actionFastForward 相应的路由为 date-time/fast-forward。

1、默认路由

如果一个URl没有指定路由,如http://www.yiifans.com,那么Yii将会使用默认的路由。
Yii在应用程序里面定义了默认的路由。默认的路由为site由yii\web\Application:: $defaultRoute定义,即控制器SiteController将会被使用。

有默认的路由也就会有默认的动作了。每个控制器都有一个默认的动作。如果在URL中没有指定动作的话,那么将会调用默认的动作。
默认的动作名为index,在yii\base\Controller:: $defaultAction中定义。
http://www.yiifans.com/?r=site,只指定了路由为site,那么将会使用默认的动作index,即将会调用SiteController里面的actionIndex方法

3、动作参数

就像上面提到的一样,一个简单的动作就是一个以actionXXX格式命名的公开的方法。那么动作如何从Http的请求中获取想要的参数呢?

1、动作中定义参数

在定义动作的时候直接定义参数。这个参数的值会直接从$_GET里面获取对应的值。也就是说动作里面定义的参数只能从$_GET里面获取值。

namespace app\controllers;
use yii\web\Controller;
class BlogController extends Controller
{
public function actionView($id, $version = null)
{
$post = Post::findOne($id);
$text = $post->text;
if ($version) {
$text = $post->getHistory($version);
}
return $this->render('view', [
'post' => $post,
'text' => $text,
]);
}
}

如上所示动作view定义了两个参数$id和$version。其中$version的默认值为null。
我们可以通过http://www.yiifans.com/?r=blog/view&id=42或者http://www.yiifans.com/?r=blog/view&id=42&version=3来访问。

在第一种情况下由于没有version参数,将会使用在定义的时候的默认值。而在第二种情况下actionView里面将得到相应的值,$id为42,$version为3.

如果在动作里面定义的参数没有默认值,而访问的URL里面又没有相对应的变量,那么会抛一个异常。如http://www.yiifans.com/?r=blog/view由于没有在URL中指定id,在action的定义中又没有默认的值,所以将会抛一个异常。

2、从请求(request)中获取参数

如果要从POST中获取参数或者GET里面的参数太多,还可以c通过Yii里面的request对象来获取相关的参数,可以通过\Yii:: $app->request来访问。如下代码所示:

namespace app\controllers;
use yii\web\Controller;
use yii\web\HttpException;
class BlogController extends Controller
{
public function actionUpdate($id)
{
$post = Post::findOne($id);
if (!$post) {
throw new NotFoundHttpException();
}
if (\Yii::$app->request->isPost) {
$post->load(Yii::$app->request->post());
if ($post->save()) {
return $this->redirect(['view', 'id' => $post->id]);
}
}
return $this->render('update', ['post' => $post]);
}
}

4、独立动作(action)

如果一个动作是通用的,要想在其它的控制器中重复使用,可以把这个动作放在一个单独的文件中实现。

创建actions/Page.php

namespace app\actions;
class Page extends \yii\base\Action
{
public $view = 'index';
public function run()
{
return $this->controller->render($view);
}
}

使用:

class SiteController extends \yii\web\Controller
{
public function actions()
{
return [
'about' => [
'class' => 'app\actions\Page',
'view' => 'about',
],
];
}
}

actions()返回的是一个name-value数组,name为动作(action)的名称,class为实现的动作的类,view为action要使用的模板文件。

访问:
http://www.yiifans.com/?r=site/about

5、动作过滤器(Action Filters)

你可能需要对控制器里面的某些动作应用一些过滤器,例如判断对当前动作的访问权限,对动作返回结果进一步处理等。

动作过滤器是yii\base\ActionFilter的子类的实例。

要使用动作过滤器,可以把它像行为一样附加在控制器或者模块上。下面这个例子实现了对index动作的缓存

public function behaviors()
{
return [
'httpCache' => [
'class' => \yii\filters\HttpCache::className(),
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}

你还可以同时使用多个动作过滤器。他们将按照在behaviors()里面定义的先后顺序依次执行。如果其中的任意一个过滤器取消了动作的执行,那么当前过滤器后面的所有的过滤器将不会被执行。同时这个动作也不会执行。

当附加一个过滤器到控制器的时候,这个过滤器可以应该于当前控制器里面所有的动作。如果附加到模块或者应用程序,这个过滤器就可以应用于这个模块或者应用程序下面的所有的动作。

要创建动作过滤器,从yii\base\ActionFilter继承并实现beforeAction() 和afterAction()方法。beforAction将在action执行之前执行,同理afterAction将在action执行之后执行。如果beforeAction()返回false,那么当前过滤器后面的所有的过滤器都将不会被执行,并且action也不会被执行。

authorization 章节介绍了yii\filters\AccessControl 过滤器,caching章节介绍了yii\filters\PageCache和yii\filters\HttpCache过滤器。在实现自定义的过滤器的时候可以参考这些内置的过滤器的实现。

6、捕获所有的请求

有时候用一个控制器和动作来处理所有的请求是非常有用的。例如在网站在处于维护的情况下显示一个通知等。如果要实现这个功能只需要设置应用程序的catchAll属性就可以了。有两种方式可以设置catchAll属性,动态的设置或者在配置文件里面设置。

return [
'id' => 'basic',
'basePath' => dirname(__DIR__),
// ...
'catchAll' => [ // <-- here
'offline/notice',
'param1' => 'value1',
'param2' => 'value2',
],
]

上面的例子是通过配置文件来设置的。offline/notice的意思是指使用OfflineController::actionNotice(),param1 和 param2 是传递给notice动作方法的参数。

7、自定义响应类

一般在动作执行完后会返回一个render之后的html内容,当然还可以返回特定的响应

  1. namespace app\controllers;
    use yii\web\Controller;
    use app\components\web\MyCustomResponse; #extended from yii\web\Response
    class SiteController extends Controller
    {
    public function actionCustom()
    {
    /*
    * do your things here
    * since Response in extended from yii\base\Object, you can initialize its values by passing in
    * __constructor() simple array.
    */
    return new MyCustomResponse(['data' => $myCustomData]);
    }
    }

原文连接:http://www.yiifans.com/forum.php?mod=viewthread&tid=35

Yii2.0中文开发向导——控制器(Controller)的更多相关文章

  1. Yii2.0中文开发向导——Yii2中多表关联查询(join、joinwith)(转)

    我们用实例来说明这一部分 表结构 现在有客户表.订单表.图书表.作者表, 客户表Customer   (id  customer_name) 订单表Order          (id  order_ ...

  2. Yii2.0中文开发向导——Yii2中多表关联查询(join、joinwith)

    我们用实例来说明这一部分 表结构 现在有客户表.订单表.图书表.作者表, 客户表Customer   (id  customer_name) 订单表Order          (id  order_ ...

  3. Yii2.0中文开发向导——删除数据

    直接 model 删除 $model = User::find($id); $model->delete(); 带有条件的删除 $connection ->createCommand() ...

  4. Yii2.0中文开发向导——自定义日志文件写日志

    头部引入log类use yii\log\FileTarget; $time = microtime(true);$log = new FileTarget();$log->logFile = Y ...

  5. Yii2.0中文开发向导——rules常用规则

    public function rules(){ return [ //必须填写 ['email, username, password,agree,verifyPassword,verifyCode ...

  6. Yii2.0中文开发向导——Where条件查询全解析

    在Yii的Model里进行查询的时候 where是必不可少的.Where方法声明为 static where( $condition ) 其中参数 $condition类型为字符串或者数组 1.字符串 ...

  7. Yii2.0源码分析之——控制器文件分析(Controller.php)创建动作、执行动作

    在Yii中,当请求一个Url的时候,首先在application中获取request信息,然后由request通过urlManager解析出route,再在Module中根据route来创建contr ...

  8. ZH奶酪:LAMP环境中如何重新部署一个Yii2.0 web项目

    使用Yii2.0 framework开发的项目,使用Github进行版本控制,现在要把这个项目部署到一个新的电脑/系统中: (1)安装LAMP (2)在/var/www/html目录下执行 git c ...

  9. 8.Yii2.0框架控制器接收get.post数据

    8.Yii2.0框架控制器接收get.post数据 一.get传参 <?php /** * Created by Haima. * Author:Haima * QQ:228654416 * D ...

随机推荐

  1. HTML学习体会

    HTML介绍 华丽的网页界面,都是由静态网页和一些动态效果,插入的视频,和flash等等,不得不说,静态网页的制作,是学习网页的必经之路,可见静态网页在学习网页的前端是十分重要.静态网页主要是通过ht ...

  2. C++ 内存管理与堆栈

    /*内存管理与堆栈: * # 一个由C/C++编译的程序占用的内存分为以下几个部分 * 1.栈区:由编译器自动分配释放,数据先进后出 * 2.堆区:由程序员手动分配释放,数据先进先出, * new 和 ...

  3. Windows Platform Predefined Macros

    https://msdn.microsoft.com/en-us/library/b0084kay.aspx

  4. Robot Framework--05 案例设计之流程与数据分离

    转自:http://blog.csdn.net/tulituqi/article/details/7651049 这一讲主要说一下案例设计了.还记得我们前面做的case么?先打开浏览器访问百度,输入关 ...

  5. jar war

    区别:Jar.war.EAR.在文件结构上,三者并没有什么不同,它们都采用zip或jar档案文件压缩格式.但是它们的使用目的有所区别: Jar文件(扩展名为. Jar,JavaApplication ...

  6. Tomcat编码问题及访问软链接文件设置

    Tomcat编码问题及访问软链接文件设置 一.编码问题:让其支持UTF-8格式 修改tomcat中server.xml Connector port=" protocol="org ...

  7. Wordpress文章图片不居中与开头缩进问题

    //段落开头缩进 .Mid2L_con p {text-indent:2em;} //文章内图片不居中(设置居中后) .Mid2L_con .aligncenter { display: block; ...

  8. Java byte位移操作 注意事项

    Java对byte 的 + - * / >> >>> << & | ^ (加,减,乘,除,右移,左移,无符号右移,位与,位或,位异或)操作,均会是首先 ...

  9. hibernate4连接mysql自动创建表之错误

    我在学习Hibernate的过程中,遇到了这样一个错误:JUnit测试通过,但是数据库中却没有创建一个表,控制台的错误信息如下: HHH000388: Unsuccessful: create tab ...

  10. mysql explain详解

    对于经常使用mysql的兄弟们,对explain一定不会陌生.当你在一条SELECT语句前放上关键词EXPLAIN,MySQL解释它将如何处理SELECT,提供有关表如何联合和以什么次序的信息.借助于 ...