20.6 ThinkPHP的视图

20.6 ThinkPHP的视图

视频讲解:光盘TMlx20ThinkPHP的视图.exe

在ThinkPHP中,视图由两个部分组成:View类和模板文件。Action控制器直接与View视图类进行交互,把要输出的数据通过模板变量赋值的方式传递到视图类,而具体的输出工作则交由View视图类来进行,同时视图类还完成了一些辅助的工作,包括调用模板引擎、布局渲染、输出替换、页面Trace等功能。为了方便使用,在Action类中封装了View类的一些输出方法,例如display、fetch、assign、trace和buildHtml等方法,这些方法的原型都在View视图类中。

20.6.1 模板定义

为了对模板文件进行更有效的管理,ThinkPHP对模板文件进行目录划分,默认的模板文件定义规则是:

模板目录/[分组名/][模板主题/]模块名/操作名+模板后缀

模板目录默认是项目下的Tpl,在定义分组的情况下,会按照分组名分开子目录,新版模板主题默认是空(表示不启用模板主题功能)。模板主题功能是为了多模板切换而设计的,如果有多个模板主题,则可以使用DEFAULT_THEME参数设置默认的模板主题名。

在每个模板主题下,是以项目的模块名为目录,然后是每个模块的具体操作模板文件。例如,User模块的add操作对应的模板文件是Tpl/User/add.html。

模板文件的默认后缀是.html,后缀可以通过TMPL_TEMPLATE_SUFFIX来配置。

如果项目启用模块分组功能(假设User模块属于Home分组),那么默认对应的模板文件就会发生变化,Tpl/ Home/User/add.html。

分组功能可以通过TMPL_FILE_DEPR参数来配置,进而简化模板的目录层次。例如,设置TMPL_FILE_DEPR等于“_”,那么默认的模板文件就变成Tpl/ Home/User_add.html。

说明

正是因为系统有了这样一种模板文件自动识别的规则,display方法才可以无须带任何参数就输出对应的模板。

20.6.2 模板赋值

模板赋值是在Action控制器中完成的,通过assign方法将控制器中获取的数据赋给模板变量。例如:

$this->assign('name', $value);

如果要同时输出多个模板变量,可以使用数组的方式进行赋值。

$array = array(); $array['name'] = 'thinkphp'; $array['email'] = '[email protected]'; $array['phone'] = '12335678'; $this->assign($array);

这样,就可以在模板文件中同时输出name、email和phone这3个变量。

20.6.3 指定模板文件

模板变量赋值后就需要调用模板文件来输出相关的变量,模板调用应用的是display方法。下面讲解如何通过display方法完成对模板的调用,如表20.4所示。

表20.4 display方法的应用

说明

在第二种用法中,不需要写模板文件的路径和后缀,严格来说,这里面的模块名和操作名并不一定需要有对应的模块或者操作,只是一个目录名称和文件名称而已。例如,项目中可能没有Public模块,更没有Public模块的menu操作,但是一样可以使用“$this->display('Public:menu'); ”输出这个模板文件。

模板变量赋值后,在指定的模板文件中进行输出,具体的输出方法需要根据选择的模板引擎来决定。如果使用的是内置的模板引擎,请参考ThinkPHP开发完全手册模板指南中的内容;如果使用PHP本身作为模板引擎,则直接在模板文件里面输出,例如“<?php echo $name.'['.$email.' '.$phone.']'; ?>”。

20.6.4 特殊字符串替换

在进行模板输出之前,系统还会对模板的特殊字符串进行替换,实现模板输出的替换和过滤。这个机制可以使得模板文件的定义更加方便,默认的替换规则如表20.5所示。

表20.5 模板中特殊字符串的替换规则

说明

这些特殊的字符串是严格区别大小写的,并且这些特殊字符串的替换规则是可以更改或者增加的。只要在项目配置文件中配置TMPL_PARSE_STRING就可以完成。如果有相同的数组索引,就会更改系统的默认规则。例如:

TMPL_PARSE_STRING =>array( '__PUBLIC__'=>'/Common', //更改默认的__PUBLIC__ 替换规则 '__UPLOAD__'=>'/Public/Uploads/', //增加新的上传路径替换规则 )

【例20.10】实现用户登录功能,将登录用户的信息存储到SESSION变量中,应用ThinkPHP中提供的分页扩展类和page方法完成数据的分页输出。(实例位置:光盘TMsl2010)

(1)定位到AppLibAction目录下,编写项目控制器。创建Index模块,继承系统的Action基础类,定义index方法,验证用户提交的用户名和密码是否正确,如果正确则将登录用户名存储到SESSION变量中,并且将网页重定向到main.html页面。其代码如下:

<?php session_start(); //初始化SESSION变量 header("Content-Type:text/html; charset=utf-8"); //设置页面编码格式 class IndexAction extends Action{ public function index(){ if(isset($_POST['user'])){ if(isset($_POST['user']) && isset($_POST['pass'])){ $db=M(); //实例化模型类,参数数据表名称,不包含前缀 $select = $db->query("select * from think_user where user='".$_POST['user']."' and pass='".$_POST['pass']."'"); //执行查询语句,验证用户名和密码是否正确 if($select){ $_SESSION['admin']=$_POST['user']; //将登录用户名存储到SESSION中 $this->redirect('Index/main', '',2, ’用户 '.$_POST['user'].' 登录成功!'); //页面重定向 }else{ $this->redirect('Index/index', '',2, ’用户名或者密码不正确!'); //页面重定向 } }else{ $this->redirect('Index/index', '',2, ’用户名、密码不能为空!'); //页面重定向 } } $this->display(); }

定义main方法,载入分页类,完成数据库中数据的分页查询,并且将查询结果赋给模板变量。其代码如下:

public function main(){ $db=M('User'); //实例化模型类,参数数据表名称,不包含前缀 // 进行分页数据查询,注意page方法的参数的前面部分是当前的页数,使用$_GET[p]获取 if(isset($_GET['p'])){ //判断分页变量是否存在 $p=$_GET['p']; }else{ $p=1; } $list=$db->where('address='.'"长春市"')->order('id desc')->page($p.',1')->select(); //查询数据 $this->assign('select', $list); //赋值数据集 import("ORG.Util.Page"); //导入分页类 $count=$db->where('address='.'"长春市"')->count(); // 查询满足要求的总记录数 $Page=new Page($count,1); //实例化分页类,传入总记录数和每页显示的记录数 $show=$Page->show(); //分页显示输出 $this->assign('page', $show); //赋值分页输出 $this->display(main); //输出模板 }

定义validatorcode方法,应用GD库中的函数,根据超链接传递的值生成用户登录的验证码。其代码如下:

public function validatorcode(){ header('content-type:image/png'); //定义标题PNG格式图像 $im=imagecreate(65,25); //定义画布 imagefill($im,0,0, imagecolorallocate($im,200,200,200)); //区域填充 $validatorCode=$_GET['code']; //获取提交的值 imagestring($im, rand(3, 5), 10, 3, substr($validatorCode, 0, 1), imagecolorallocate($im, 0, rand(0, 255), rand(0, 255))); imagestring($im, rand(3, 5), 25, 6, substr($validatorCode, 1, 1), imagecolorallocate($im, rand(0, 255), 0, rand(0, 255))); imagestring($im, rand(3, 5), 36, 9, substr($validatorCode, 2, 1), imagecolorallocate($im, rand(0, 255), rand(0, 255), 0)); imagestring($im, rand(3, 5), 48, 12, substr($validatorCode, 3, 1), imagecolorallocate($im, 0, rand(0, 255), rand(0, 255))); imagepng($im); //生成PNG图像 imagedestroy(); //销毁图像 }

(2)定位到AppTpl目录下,创建Index模块文件夹。编辑index操作的模板文件index.html,载入css样式文件和javascript文件,创建表单,完成用户登录信息的提交操作。其关键代码如下:

<link href="__ROOT__/Public/Css/style.css" rel="stylesheet" type="text/css" /> <js href="__ROOT__/Public/Js/check.js" /> <form name="form1"method="post" action="__URL__/index"onSubmit="return chkinput(this)"> <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 type="text" name="validatorCode" size="10" /> <input type="hidden" name="defValidatorCode" value="" /> <script language="Javascript"> var num1=Math.round(Math.random()*10000000); //生成随机数 var num=num1.toString().substr(0,4); //截取随机数的前4个字符 //将截取值传递到图像处理页中 document.write("<img name=codeimg src='__URL__/validatorcode? code="+num+"'>"); form1.defValidatorCode.value=num; //将截取值赋给表单中的隐藏域 function reCode(){ //定义方法,重新生成验证码 var num1=Math.round(Math.random()*10000000); //生成随机数 var num=num1.toString().substr(0,4); //截取随机数 document.codeimg.src="__URL__/validatorcode? code="+num; //将截取值传递到图像处理页中 form1.defValidatorCode.value=num; //将截取值赋给表单中的隐藏域 } </script> <a href="javascript:reCode()" class="content">看不清</a> </td> </tr> </table> <input type="image" name="imageField" id="imageField" src="__ROOT__/Public/images/66_05.gif" /> </form>

(3)在Index模块文件夹下,编辑main.html文件,通过模板引擎中的session标签输出当前登录的用户名,通过foreach标签循环输出模板变量传递的数据,最后输出模板变量传递的分页超链接。其关键代码如下:

<table width="405" border="1" cellpadding="1" cellspacing="1" bgcolor="#99CC33" bordercolor="#FFFFFF"> <tr> <td colspan="3" bgcolor="#FFFFFF" class="title" align="center">当前登录用户:{$Think.session. admin}</td> </tr> <foreach name='select' item='user' > <tr class="content"> <td bgcolor="#FFFFFF">&nbsp; {$user.id}</td> <td bgcolor="#FFFFFF">&nbsp; {$user.user}</td> <td bgcolor="#FFFFFF">&nbsp; {$user.address}</td> </tr> </foreach> <tr class="content"> <td colspan="3" bgcolor="#FFFFFF">&nbsp; {$page}</td> </tr> </table>

其运行结果如图20.18所示。

图20.18 用户登录和数据的分页输出

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

微信扫一扫

微信扫一扫

微信扫一扫,分享到朋友圈

20.6 ThinkPHP的视图