周六和周日休息了两天,今天我就根据完全开发手册说明控制器使用的顺序,逐个说说我个人的理解。高手和tp框架使用很熟练的直接跳过!
第一:定义,由于tp框架基于MVC模式,故对于新手来说,掌握控制器的使用是必修课。(这里我默认是未修改过application/config.php配置文件以及tp5初始目录结构)
官方给出一个典型的控制器例子:
namespace app\index\controller;
class Index
{
public function index()
{
return 'index';
}
}
这里除了<?php 外,第二行就是namespace,也就是命名空间。对于新手来说,你就理解为你平常操作window的文件夹一样,是一个目录结构就可以了。主要作用就是避免函数重名、同一个类文件中方法重名,大家知道,php是不允许函数重名的,否则会报致命错误的。假设有多个一样名称方法var_dump,位于不同命名空间\app\index\controller和\tihink,有了命名空间,就相当于告诉php解析器,这个var_dump 是路径:application/index/controller\class.php中的。另一个var_dump是路径:thinkphp/library/think/class.php中,这样,php解释器不会把两者和系统自带的var_dump()混为一谈了。
总结:简而言之,你就把命名空间理解为一个具有对应目录路径关系的东西来区别同名方法就好了。至于有人问到明明目录是application为什么用app呢?这是application目录下config.php配置文件定义的。'app_namespace' => 'app'。
那么我们的访问路径应该如何填入浏览器上呢?假设你tp5rc4下载到了web根目录webroot下,那么完整的url地址应为:http://localhost/tp5rc4/pulibc/index.php/index/index/index.html,由于config.php定义了默认的模块、控制器、方法皆为index,如下图:
// 默认模块名
'default_module' => 'index',
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
在加上apache服务器默认加载index.php或者index.html,故简单的url地址为:http://localhost/tp5rc4/public
这时,你运行将会看到熟悉的tp界面。
当然,用过tp3.2.2版本的,细心一点就会发现除了命名空间有变化外,类的定义也有变化
tp3.2.2版本控制器是需要继承think命名空间下的Controller类的。而现在tp5可以无须继承该类。这也是tp5吸引我的地方。
另外控制器里tp3.2.2最常见的就是$this -> display(模板名);tp5则更为灵活,输出可多样化,结合配置文件配置(例如:'default_return_type' => 'json',),直接return一个关联数组,就可以达到之前版本$this ->ajaxReturn(array(...));的效果。而输出到模板,尽管有助手函数view(),但我更喜欢类laravel风格:$view = new \think\View(); return $view-> fetch(模版名); (话外,就当装逼吧!哈哈。。。)
关于控制器就简单分享这些心得吧,主要是分享给新手。
第二:关于控制器初始化,我觉得没什么好讲的。主要介绍一个\think\Controller类的一个方法_initialize
tp3.2.2源码我看过一点点,在构造方法中调用了该方法,但内容为空,因此继承过\think\Controller类的控制器,如果在子类控制器中加入该方法,那么实例化时,必然会调用该方法。
总结:该方法可用于做权限控制。具体做法是:用一个基类继承\think\Controller类,重写_initialize()方法,里面可加检查权限判断代码,然后将所有需要权限控制的控制器继承该基类,便可实现权限控制。具体代码自行百度tp官方权限控制。
第三:前置操作,顾名思义,也就是在url访问某方法之前要执行的方法。
这个虽然知道,但在项目里没有应用过,秉着对新手负责的态度,我还是做了测试。
直接将完全手册的代码复制过来了。如下图:
namespace app\index\controller;
use think\Controller;
class Index extends Controller //这里继承了think的Controller类
{
//保护属性,前置方法列表,键名为前置方法名,键名所指向的数组则为附加条件。
protected $beforeActionList = [
'first', //这里前置方法无其它附加条件,一定会执行。
'second' => ['except'=>'hello'], //这里前置方法是除了hello方法外才会执行。
'three' => ['only'=>'hello,data'], //这里前置方法是仅适用于hello,data两个方法才执行。
];
protected function first()
{
echo 'first<br/>';
}
protected function second()
{
echo 'second<br/>';
}
protected function three()
{
echo 'three<br/>';
}
public function hello()
{
return 'hello';
}
public function data()
{
return 'data';
}
}
下面我们一次访问index控制器的hello方法和data方法。看看两者的执行结果
1.访问hello方法,浏览器键入地址:http://localhost/tp5rc4/public/index.php/index/index/hello.html,返回结果如下:
first
three
hello
我们来结合我在代码中给出的注释分析一下,前置方法列表说明first保护方法是任何该控制器的公有方法都会执行的。second方法看到我们访问hello方法,她不高兴了,也就不为hello开门了。而three方法说我的好基友只有hello,和data,所以它也会执行,这三个前置方法执行完毕,就名正言顺执行hello自己的方法了。因此依次输出如上结果!
2,访问data方法,返回结果如下:
first
second
three
data
结果,聪明的你自行分析吧!我要睡觉了,困死了。。。