控制器(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. scrapy1_官网教程

    https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html 本篇文章主要介绍如何使用编程的方式运行Scrapy爬虫. 在开始本文之 ...

  2. oc必须知道的知识点

    id数据类型 1.通用的指针类型 2.没有*号 3.使用id类型时,不能给对象的属性或成员变量进行赋值 4.可以对其发送任何(存在的)消息   import与@class的区别 1.import会包含 ...

  3. 20145212 《Java程序设计》第1周学习总结

    20145212 <Java程序设计>第1周学习总结 教材学习内容总结 看了毕向东老师的视频,我对Java有了进一步的了解.相比于其他的计算机编程语言(比如C语言),Java有一大特点就是 ...

  4. UITextView限制输入文字

    一.设置UITextView的delegate为控制器 二.实现代理方法 #pragma mark - UITextViewDelegate - (BOOL)textView:(UITextView ...

  5. HighCharts学习笔记(二)HighCharts结构及详细配置

    HighCharts结构及详细配置: 一.HighCharts整体结构: 通过查看API文档我们知道HighCharts结构如下:(API文档在文章后面提供下载) var chart = new Hi ...

  6. Creating a ZIP Archive in Memory Using System.IO.Compression

    Thanks to http://stackoverflow.com/a/12350106/222748 I got: using (var memoryStream = new MemoryStre ...

  7. spring 容器技术入门

    官方文档 翻译 https://waylau.gitbooks.io/spring-framework-4-reference/content/III.%20Core%20Technologies/C ...

  8. [Unity] 常用技巧收集

    Unity 屏幕旋转 void Update () { //处理横向两个方向旋转 if(Input.deviceOrientation == DeviceOrientation.LandscapeLe ...

  9. html 表格head头部不动 body部分滚动,每格宽同内容增加

    如下图同Excel表格首行固定: <style> .table{ width: 100%; border-collapse:collapse; border-spacing:0;} .ta ...

  10. C-函数与内存剖析

    功能,封装,调用 形参:定义函数时函数名后面中的参数,形式参数 实参:调用函数时传入的具体数据 return作用:1退出函数 2返回一个具体数值给调用者 返回值: 如果不明确声明返回值类型,默认就是i ...