20.4 ThinkPHP的控制器
视频讲解:光盘TMlx20ThinkPHP的控制器.exe
20.4.1 控制器
ThinkPHP的控制器就是模块类,通常位于项目的LibAction目录下。类名就是模块名加上Action后缀,例如,IndexAction类表示Index模块。控制器类必须继承系统的Action基础类,这样才能确保使用Action类内置的方法。
而index操作其实就是IndexAction类的一个公共方法,所以在浏览器中输入http://localhost/myApp/index.php/Index/index/,其实就是执行IndexAction类的index(公共)方法。
【例20.3】对自动生成的项目目录中的控制器进行修改,使其输出自己编译的内容。(实例位置:光盘TMsl203)
操作步骤如下:
(1)创建名称为3的项目,将ThinkPHP核心类库存储于3目录下。
(2)编写入口文件index.php,将其存储于3目录下。index.php文件代码如下:
<?php define('THINK_PATH', '../ThinkPHP/'); //定义ThinkPHP框架路径(相对于入口文件) define('APP_NAME', '3'); //定义项目名称 define('APP_PATH', './'); //定义项目路径 require(THINK_PATH."/ThinkPHP.php"); //加载框架入口文件 ?>
(3)运行index.php文件,在3目录下自动生成项目目录,其运行结果如图20.11所示。
图20.11 自动创建项目目录
(4)在默认生成的项目目录中,控制器IndexAction中输出的是ThinkPHP设置的内容,此处对这个内容进行修改,输出“明日科技欢迎您!”。IndexAction.class.php文件修改后的代码如下:
<?php class IndexAction extends Action{ public function index(){ header("Content-Type:text/html; charset=utf-8"); //设置编码格式 echo "<div style='font-weight:normal; color:blue; float:left; width:345px; text-align:center; border:1px solid silver; background:#E8EFFF; padding:8px; font-size:14px; font-family:Tahoma'>^_^ <span style='font-weight:bold; color:red'>明日科技欢迎您!</span></div>"; //输出内容 } } ?>
在对控制器的内容进行修改后,重新运行项目,在IE浏览器中输入http://localhost/TM/sl/20/3/index.php,将输出如图20.12所示的效果。
图20.12 输出控制器中的内容
说明
每个模块的操作并非一定要定义操作方法,如果只是希望输出一个模板,既没有变量,也没有任何的业务逻辑,那么只要按照规则定义好操作对应的模板文件即可,而不需要定义操作方法。例如,在IndexAction中如果没有定义help方法,但是存在对应的Index/help.html模板文件,那么http://localhost/TM/sl/20/index.php/Index/help/依然可以正常运作,因为系统找不到IndexAction类的help方法,会自动定位到Index模块的模板目录中查找help.html模板文件,然后直接输出。
20.4.2 跨模块调用
在开发过程中经常会在当前模块调用其他模块的方法,这个时候就涉及跨模块调用。下面通过A和R两个快捷方法完成跨模块调用。
A方法表示实例化某个模块,例如在当前模块调用User模块的insert操作方法,关键代码如下:
$User=A("User"); //实例化UserAction控制器对象 $User->insert(); //调用User模块的insert操作方法
这里的A("User")是一个快捷方法,与下面的代码等效:
$User = new UserAction(); $User->insert();
事实上,在这个例子里面还有比A方法更简单的调用方法,这就是R方法,R方法表示调用一个模块的某个操作方法,例如:
R("User/insert"); //调用当前项目User模块的insert操作方法
上面只是在当前项目中调用,如果需要在多个项目之间调用方法,一样可以完成。例如调用Admin项目下的UserAction控制器的insert操作方法,关键代码如下:
$User=A("Admin://User"); //实例化Admin项目的UserAction控制器对象 $User->insert(); //调用Admin项目UserAction控制器的insert操作方法
如果使用R方法,则上面的代码可以简化为:
R("Admin://User/insert"); //调用Admin项目UserAction控制器的insert操作方法
【例20.4】应用跨模块调用的方法,在前台控制器中调用后台项目中的insert方法完成用户信息的添加操作。(实例位置:光盘TMsl204)
操作步骤如下:
(1)创建4项目根目录,在根目录下分别创建前台项目文件夹Home、后台项目文件夹Admin和Public文件夹存储css、图片和JS脚本等文件。
(2)在4项目根目录下,编辑index.php前台入口文件和admin.php后台入口文件。其关键代码如下:
//index.php前台入口文件 <?php define('THINK_PATH', '../ThinkPHP/'); //定义ThinkPHP框架路径(相对于入口文件) define('APP_NAME', 'Home'); //定义项目名称 define('APP_PATH', './Home/'); //定义项目路径 require(THINK_PATH."/ThinkPHP.php"); //加载框架入口文件 ?> //admin.php后台入口文件 <?php define('THINK_PATH', '../ThinkPHP/'); //定义ThinkPHP框架路径(相对于入口文件) define('APP_NAME', 'Admin'); //定义项目名称 define('APP_PATH', './Admin/'); //定义项目路径 require(THINK_PATH."/ThinkPHP.php"); //加载框架入口文件 ?>
(3)在IE浏览器中运行前台和后台的入口文件,自动生成项目目录。
(4)定位到AdminConf目录下,编辑config.php文件,完成后台项目中数据库的配置。其代码如下:
<?php return array( 'APP_DEBUG'=>false, //关闭调试模式 'DB_TYPE'=>'mysql', //数据库类型 'DB_HOST'=>'localhost', //数据库服务器地址 'DB_NAME'=>'db_database20', //数据库名称 'DB_USER'=>'root', //数据库用户名 'DB_PWD'=>'111', //数据库密码 'DB_PORT'=>'3306', //数据库端口 'DB_PREFIX'=>'think_', //数据表前缀 ); ?>
(5)定位到AdminLibAction目录下,编写后台项目的控制器。首先创建Index模块,继承系统的Action基础类,定义index方法读取指定数据表中的数据,并且将查询结果赋给模板变量,最终指定模板页。IndexAction.class.php的代码如下:
<?php header("Content-Type:text/html; charset=utf-8"); //设置页面编码格式 class IndexAction extends Action{ public function index() { $db=new Model('user'); //实例化模型类,参数数据表名称,不包含前缀 $select=$db->select(); //查询数据 $this->assign('select', $select); //模板变量赋值 $this->display(); //输出模板 } } ?>
然后创建User模块,同样继承系统的Action基础类,定义insert方法,实例化模型类,将表单中提交的数据添加到指定的数据表中,添加成功后重定向到后台主页。UserAction.class.php的代码如下:
<?php header("Content-Type:text/html; charset=utf-8"); //设置页面编码格式 class UserAction extends Action{ //定义类,继承基础类 public function insert(){ //定义方法 $ins=new Model('user'); //实例化模型类,传递参数为没有前缀的数据表名称 $ins->Create(); //创建数据对象 $result=$ins->add(); //写入数据库 $this->redirect('Index/index', '',5, ’页面跳转中’); //页面重定向 } } ?>
(6)定位到AdminTpl目录下,首先创建Index模块文件夹,编辑index操作的模板文件index.html,循环输出模板变量传递的数据。index.html模板文件的关键代码如下:
<volist name='select' id='user' > <tr class="content"> <td bgcolor="#FFFFFF"> {$user.id}</td> <td bgcolor="#FFFFFF"> {$user.user}</td> <td bgcolor="#FFFFFF"> {$user.address}</td> </tr> </volist>
然后创建User模块文件夹,编辑insert操作的模板文件index.html,创建添加用户信息的表单。其关键代码如下:
<form method="post" action="__URL__/insert"> <table width="265" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="title" id="td">用户名:</td> <td><input name="user" type="text" size="15" /></td> </tr> <tr> <td class="title" id="td">密码:</td> <td><input name="pass" type="password" size="15" /></td> </tr> <tr> <td class="title" id="td">地址:</td> <td><input name="address" type="text" size="20" /></td> </tr> </table> <input type="image" name="imageField" id="imageField" src="__ROOT__/Public/images/66_05.gif" /> </form>
(7)定位到HomeConf目录,编辑前台项目的数据库配置文件config.php。
(8)定位到HomeLibAction目录,创建前台项目控制器Index。定义index方法查询数据库中的用户信息,并且将查询结果赋给模板变量;定义insert方法,通过R快捷方式调用Admin项目UserAction控制器的insert操作方法完成数据的添加操作。IndexAction.class.php的代码如下:
<?php header("Content-Type:text/html; charset=utf-8"); //设置页面编码格式 class IndexAction extends Action{ public function index() { $db=new Model('user'); //实例化模型类,参数数据表名称,不包含前缀 $select=$db->select(); //查询数据 $this->assign('select', $select); //模板变量赋值 $this->display(); //输出模板 } public function insert() { R("Admin://User/insert"); //远程调用Admin项目UserAction控制器的insert操作方法 } } ?>
(9)定位到HomeTpl目录下,创建Index模块文件夹,编辑index操作的模板文件index.html。在index.html模板文件中,创建表单提交用户注册信息,循环输出模板变量传递的数据。
(10)在IE浏览器中输入http://localhost/TM/sl/20/4/index.php,其运行结果如图20.13所示。
图20.13 跨模块调用完成用户注册
技巧
Action类的redirect方法可以实现页面的重定向功能。redirect方法的定义规则如下(方括号内参数根据实际应用决定):
redirect ('[项目://][路由@][分组名-模块/]操作? 参数1=值1[&参数N=值N]')
或者用数组的方式传入参数:
redirect ('[项目://][路由@][分组名-模块/]操作’, array(’参数1'=>’值1' [, ’参数N'=>’值N'])) 如果不定义项目和模块,就表示当前项目和模块名称。例如: $this->redirect('Index/index', '',5, ’页面跳转中’); //页面重定向
停留5秒后跳转到Index模块的index操作,并且显示页面跳转中字样,重定向后会改变当前的URL地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。