thinkphp学习2-控制器
1.定义控制器
一般来说,ThinkPHP的控制器是一个类,而操作则是控制器类的一个公共方法。
控制器通常需要继承系统的Controller类或者其子类,例如,下面定义了一个 \Home\Controller\IndexController
控制器类:
<?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function hello(){ echo 'hello'; } public function test(){ echo 'test'; } } ?>
控制器的名称采用驼峰法命名(首字母大写),操作方法的定义必须是公共方法,否则会报操作错误。
IndexController控制器类的hello和test方法就是操作方法,通过下面的URL地址访问控制器方法:
http://serverName/Home/Index/hello
http://serverName/Home/Index/test
2.实例化控制器
访问控制器的实例化通常是自动完成的,系统会根据URL地址解析出访问的控制器名称自动实例化,并且调用相关的操作方法。
如果你需要跨控制器调用的话,则可以单独实例化:
// 实例化Home模块的User控制器 $user = new \Home\Controller\UserController();
系统为上面的控制器实例化提供了一个快捷调用方法A,上面的代码可以简化为:
// 假设当前模块是Home模块 $user = A('User'); $blog = A('Admin/Blog');
3.前置和后置操作
前置和后置操作指的是在执行某个操作方法之前和之后会自动调用的方法,不过仅对访问控制器有效。
前置和后置操作的定义方式如下:
<?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller{ //前置操作方法 public function _before_index(){ echo 'before<br/>'; } public function index(){ echo 'index<br/>'; } //后置操作方法 public function _after_index(){ echo 'after<br/>'; } }
如果我们访问 http://serverName/index.php/Home/Index/index
结果会输出
before
index
after
4.Action参数绑定
参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块、控制器和操作名)和操作方法中的参数进行绑定。
要启用参数绑定功能,首先确保你开启了URL_PARAMS_BIND
设置:
'URL_PARAMS_BIND' => true, // URL变量绑定到操作方法作为参数
默认的参数绑定方式是按照变量名进行绑定,例如:
namespace Home\Controller; use Think\Controller; class BlogController extends Controller{ public function read($id){ echo 'id='.$id; } public function archive($year='2013',$month='01'){ echo 'year='.$year.'&month='.$month; } }
当访问URL地址:
http://serverName/index.php/Home/Blog/read/id/5
http://serverName/index.php/Home/Blog/archive/year/2013/month/11
两个URL地址中的id参数和year和month参数会自动和read操作方法以及archive操作方法的同名参数绑定。
按照变量名进行参数绑定的参数必须和URL中传入的变量名称一致,但是参数顺序不需要一致。
如果使用下面的URL地址进行访问,参数绑定仍然有效:
http://serverName/index.php?c=Blog&a=read&id=5
http://serverName/index.php?c=Blog&a=archive&year=2013&month=11
如果用户访问的URL地址是:
http://serverName/index.php/Home/Blog/read/
那么会抛出下面的异常提示: 参数错误:id
报错的原因很简单,因为在执行read操作方法的时候,id参数是必须传入参数的,但是方法无法从URL地址中获取正确的id参数信息。由于我们不能相信用户的任何输入,因此建议你给read方法的id参数添加默认值,例如:
public function read($id=0){ echo 'id='.$id; }
始终给操作方法的参数定义默认值是一个避免报错的好办法。
第二种方式是按照变量的顺序绑定,这种情况下URL地址中的参数顺序非常重要,不能随意调整。要按照变量顺序进行绑定,必须先设置URL_PARAMS_BIND_TYPE
为1:
'URL_PARAMS_BIND_TYPE' => 1, // 设置参数绑定按照变量顺序绑定
操作方法的定义不需要改变,URL的访问地址分别改成:
http://serverName/index.php/Home/Blog/read/5
http://serverName/index.php/Home/Blog/archive/2013/11
5.AJAX返回
系统的\Think\Controller类提供了ajaxReturn方法用于AJAX调用后返回数据给客户端。并且支持JSON、JSONP、XML和EVAL四种方式给客户端接受数据,并且支持配置其他方式的数据格式返回。如果是EVAL方式的话,只会输出字符串data数据。
ajaxReturn方法调用示例:
$data['status'] = 1; $data['content'] = 'content'; $this->ajaxReturn($data);
默认配置采用JSON格式返回数据(通过配置DEFAULT_AJAX_RETURN进行设置),我们可以指定格式返回,例如:
// 指定XML格式返回数据 $data['status'] = 1; $data['content'] = 'content'; $this->ajaxReturn($data,'xml');
默认的JSONP格式返回的处理方法是jsonpReturn
,如果你采用不同的方法,可以设置:
'DEFAULT_JSONP_HANDLER' => 'myJsonpReturn', // 默认JSONP格式返回的处理方法
或者直接在页面中用callback参数来指定。
如下:http://localhost:81/myapp/home/index/test?callback=jsCallback
输出为:
jsCallback({"name":"\u5468\u5bcc\u6c11","age":26});
6.跳转和重定向
系统的\Think\Controller类内置了两个跳转方法success和error,用于页面跳转提示,而且可以支持ajax提交。
success和error方法的第一个参数表示提示信息,第二个参数表示跳转地址,第三个参数是跳转时间(单位为秒),例如:
// 操作完成3秒后跳转到 /Article/index $this->success('操作完成',U('/Article/index'),3); // 操作失败5秒后跳转到 /Article/error $this->error('操作失败',U('/Article/error'),5);
跳转地址是可选的,success方法的默认跳转地址是$_SERVER["HTTP_REFERER"]
,error方法的默认跳转地址是javascript:history.back(-1);
。
默认的等待时间success方法是1秒,error方法是3秒
success和error方法会自动判断当前请求是否属于Ajax请求,如果属于Ajax请求则会调用ajaxReturn方法返回信息。 ajax方式下面,success和error方法会封装下面的数据返回:
$data['info'] = $message; // 提示信息内容 $data['status'] = $status; // 状态 如果是success是1 error 是0 $data['url'] = $jumpUrl; // 成功或者错误的跳转地址
Controller类的redirect方法可以实现页面的重定向功能。
redirect方法的参数用法和U函数的用法一致,例如:
//重定向到New控制器的Category操作 $this->redirect('New/category', array('cate_id' => 2), 5, '页面跳转中...');
7.URL生成
ThinkPHP内置提供了U方法,用于URL的动态生成,可以确保项目在移植过程中不受环境的影响。
U方法的定义规则如下(方括号内参数根据实际应用决定):
U('地址表达式',['参数'],['伪静态后缀'],['显示域名'])
地址表达式的格式定义如下:
[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...
如果不定义模块的话 就表示当前模块名称,下面是一些简单的例子:
U('User/add'); // 生成User控制器的add操作的URL地址 U('Blog/read?id=1'); // 生成Blog控制器的read操作 并且id为1的URL地址 U('Admin/User/select'); // 生成Admin模块的User控制器的select操作的URL地址
U方法的第二个参数支持数组和字符串两种定义方式,如果只是字符串方式的参数可以在第一个参数中定义,例如:
U('Blog/cate',array('cate_id'=>1,'status'=>1)); U('Blog/cate','cate_id=1&status=1'); U('Blog/cate?cate_id=1&status=1');
注意:如果你是在模板文件中直接使用U方法的话,需要采用 {:U('参数1', '参数2'…)} 的方式。