一般来说,ThinkPHP的控制器是一个类,而操作则是控制器类的一个公共方法。下面我们就来详细谈谈ThinkPHP的控制器
在上一课程中,你可能会对ThinkPHP的路由会有一丝丝疑惑,不过没关系,学完本课程,很多事都会豁然开朗。
控制器文件命名遵守IndexController.class.php的方式
控制器的定义
在开始之前,我们还是需要明确一下控制器的定义:
" .$id; } public function top(){ echo "top page "; } }
如所见,前面在路由篇提到的控制器就是这么定义的:
使用相应的命名空间,默认是namespace Home\Controller
加载Think\Controller
新建控制器继承于Controller(或子类)
采用驼峰命名法,注意首字母大写
控制器内的公共方法可以看作一个操作,比如上面的read()和top()方法就可以看作操作,我们在路由篇的时候都验证过了。
:8999/index.php/Home/Index/top
就是访问到top()方法,会在页面上打印出top page ,再次明确Home代表的是Home模块
有时候可能会遇到有和系统的关键字冲突的方法,这时候就可以使用设置操作方法后缀来解决了,具体请看官方文档:
前置和后置操作
前置和后置操作指的是在执行某个操作方法之前和之后会自动调用的方法,不过仅对访问控制器有效,如在IndexController中为top()方法添加前置后置方法:
public function _before_top(){ echo "before top page "; } public function top(){ echo "top page "; } public function _after_top(){ echo "after top page "; }
访问::8999/index.php/Home/Index/top
就会看到打印出:
before top page top page after top page
使用前置和后置操作要注意如下两点:
如果当前的操作并没有定义操作方法,而是直接渲染模板文件,那么如果定义了前置和后置方法的话,依然会生效。真正有模板输出的可能仅仅是当前的操作,前置和后置操作一般情况是没有任何输出的。
需要注意的是,在有些方法里面使用了exit或者错误输出之类的话 有可能不会再执行后置方法了。例如,如果在当前操作里面调用了系统Action的error方法,那么将不会再执行后置操作,但是不影响success方法的后置方法执行
可以用于表单的过滤和验证
参数绑定
参数绑定是通过直接绑定URL地址中的变量作为操作方法的参数,可以简化方法的定义甚至路由的解析。
'URL_PARAMS_BIND' => true
参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块、控制器和操作名)和操作方法中的参数进行绑定。
参数绑定有两种方式:按照变量名绑定和按照变量顺序绑定,默认使用的是按照变量名绑定,比如看下面的例子:
public function read($id){ echo "read page with ".$id; } public function archive($year, $month){ echo "$year ".$month; }
对,这个就是上一篇路由所涉及的内容,在之前路由的路由设置处
'blogs/:id' => array('Index/read')
我们将:id直接映射给read()方法的参数$id,所以现在回头再看,其实路由规则就是给了你一个自定义URL的功能。如果去掉上面的路由设置,我们正确的访问方式是:
:8999/Home/index/read/id/3
上面的URl中id就是变量名,如果你写成:
public function read($title){ echo "read page with ".$title; }
那么访问地址就是:
:8999/index.php/Home/index/read/title/3
对于多个参数绑定的情况,只要将相应的变量名和值传进来就可以了,不在乎顺序,比如下面两个会返回相同的结果:
:8999/index.php/Home/index/archive/year/2012/month/12
:8999/index.php/Home/index/archive/month/12/year/2012
需要注意的是,不管那种情况之下,当你访问
:8999/index.php/Home/index/read/
是会报错的:
参数错误或者未定义:id
解决的一个好方法就是,给绑定的参数设置默认值,比如:
public function read($id=0){ echo "read page with ".$id; }
这样再次访问上面的URL,就会输出:
read page with
0
tips:给绑定参数设置默认值是一个避免报错的好办法
在实际的开发中,我们其实会见到没有显示变量名这样的URL,如:
:8999/index.php/Home/index/read/3
怎么解决呢?这个时候,我们其实就可以用到第二种参数绑定:按照变量顺序绑定。要使用这种参数绑定,需要先在设置项中设置:
'URL_PARAMS_BIND_TYPE' => 1
一旦设置变量顺序绑定,这种情况下URL地址中的参数顺序非常重要,不能随意调整。这种情况下操作方法的定义不需要改变,只是访问的URL变了而已,现在用上面的方式访问就可以正确访问了。
如果在变量顺序绑定的情况下,我们访问:
:8999/index.php/Home/index/archive/2012/12
:8999/index.php/Home/index/archive/12/2012
这两个结果显然是不一样,后者并不是我们想要的。所以这种情况需要严格遵守顺序来传值。
伪静态
URL伪静态通常是为了满足更好的SEO效果,ThinkPHP支持伪静态URL设置,可以通过设置URL_HTML_SUFFIX参数随意在URL的最后增加你想要的静态后缀,,而不会影响当前操作的正常执行,默认情况下,伪静态的设置为html。但我们可以自己设置,例如
'URL_HTML_SUFFIX'=>'shtml'
如果希望支持多个伪静态后缀,可以直接设置如下:
'URL_HTML_SUFFIX' => 'html|shtml|xml'
如果此项设置留空则表示可以支持所有的静态后缀。
也可以设置禁止访问的URL后缀通过URL_DENY_SUFFIX来设置,例如:
'URL_DENY_SUFFIX' => 'pdf|ico|png|gif|jpg',
注: URL_DENY_SUFFIX的优先级比URL_HTML_SUFFIX要高。
URL生成
为了配合所使用的URL模式,我们需要能够动态的根据当前的URL设置生成对应的URL地址,为此,ThinkPHP内置提供了U方法,用于URL的动态生成,可以确保项目在移植过程中不受环境的影响。
定义规则
U方法的定义规则如下(方括号内参数根据实际应用决定):
U('地址表达式',['参数'],['伪静态后缀'],['显示域名'])
地址表达式
地址表达式的格式定义如下:
[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...
如果不定义模块的话 就表示当前模块名称,下面是一些简单的例子: