注:载入类文件语句:require 'includes/Template.class.php';也可以定义__autoload函数,实例化对象的时候会自动载入:
在浏览器中输入:http://localhost/tpl/index.php
注:我们尽量设置php文件和tpl文件名字是一样的,这样载入的时候我们就不需要通过参数传递指定文件的名字,直接就用当前执行的文件名字的模板文件就可以了,php文件的名字是index,我们的tpl文件也设置为index。
在载入模板前要先判断模板文件是否存在!
相关函数解释:
basename(path,suffix):返回路径中的文件名部分。suffix参数可选,规定文件扩展名,如果文件有suffix,则不输出该扩展。
$_SERVER['SCRIPT_FILENAME']:当前执行脚本的绝对路径及文件名
__FILE__:原始文件的绝对路径及文件名
在这个项目中,我们是在index.php中执行display函数,所以用$_SERCRE[SCRIPT_FILENAME]的值为:ROOT_PATH.'index.php';用__FILE__的值为ROOT_PATH.'/includes/Template.class.php',我们所执行的php文件不同,模板文件相对应不同,所以我们用$_SERVER['SCRIPT_FILENAME']
上图中的$_fileName为:index.tpl
在浏览器中输入:http://localhost/tpl/index.php
在浏览器中输入:http://localhost/tpl/index.php
注:$this->_config["$_tag->name"] = "$_tag->value"中$_tag->name必须加引号(必须是双引号,因为单引号不可以解析变量),因为$_tag->name不是字符串,而是一个对象,如果不加引号会报错:Illegal offset type。$_tag->value的引号可加可不加。
在浏览器中输入:http://localhost/tpl/index.php
注:(1)后台首页定义为admin.php 但是如果我们想要进入后台页面,需要在浏览器中输入http://localhost/tpl/admin/admin.php,系统默认的页面是index.php,所以我们新建index.php文件,添加语句:header('location:admin.php');将默认的页面导向admin.php,这样,当我们想要进入后台主页的时候,直接在浏览器中输入http://localhost/tpl/admin就可以了。(2)dirname()函数返回路径中的目录部分,dirname(__FILE__)表示当前文件的目录,即当前文件路径的上一层,也就是当前文件所在文件夹,如果再加一层dirname即dirname(dirname(__FILE__))则表示文件所在文件夹所在的目录,即文件所在文件夹的上层文件夹路径
前台首页
列表页:
后台
注意:unDB 函数的参数要按地址传递才可以将对象真正销毁
完善增加管理员用户的页面
注意:添加用户时,获取的值要加引号!!!
注意:在入口文件要引入基类文件model.class.php
1.新建一个属性$_model用来存放manage类实例,将业务流程中的$this换成$this->_model
2.将增删改查业务流程分别封装到函数中,直接用self调用
3.在manage入口文件中引入该控制器文件:ManageAction.class.php
4.在manage入口文件中直接实例化ManageAction对象
注意:两个对象句柄要修改为protected才可以被子类调用!
注意:
1.因为修改管理员需要传用户id,所以只能从列表页进去,那么只有在修改管理员页面才会显示修改管理员的这个子导航
2.在哪个页面,相对于那个子导航应该要有不同的样式,并且不可以点击
3.不可以点击需要实现两点,没有手型和没有href属性。
manage.php页面的删除页面可以删除,因为有了二级导航,那个列表页面下方的增加管理员和修改管理员与增加管理员页面的返回列表都可以删除
1.增加一个属性$table用来存放表名,之后就不需要传表名这个参数了
2.修改记录仅需要传入表名和条件就可以了,表名用$this->table表示即可,鉴于有多条件也有单条件,所以我们传入两个参数,一个是条件的字段名(字符串),一个是条件的值(数组),如果之前的语句中已经有了where关键字则不需要加where而是and
3.sql语句中的条件连接在查询修改时都需要,所以封装成一个私有函数调用
如果增删改模型参数传错了,有时候会返回-1也是添加失败,但是-1也是真,所以要修改成功的条件是必须返回值必须等于1
注意:
1.删除cms_level中的level字段,以后可以直接用id表示就可以了,那么获取管理员列表的时候关联两个表的条件就要做出相应修改
2.在查询管理员数据中涉及到了一个时间的问题,等级列表里面是没有的,这个获取多个数据模型要稍微修改一下,要加一个判断避免出错!按理来说是模型基类是不应该存在固定字段的,这个以后再优化!
1.修改管理员前台页面,增加密码确认输入框
2.增加验证类,增加两个函数,一个验证长度是否满足,一个验证两个数据是否相等
3.在增加和修改管理员之前要验证
4.当修改管理员时,如果密码没有输入,则不修改密码,而不是密码设置为空
注:判断之前查询出的数据要检查是不是当前记录,如果不是当前记录才会提示登记名已经存在!
分析:
1.创建分页我们需要两个参数传递,数据总条数(从数据库中查询)和每页显示记录的条数
2.分页需要知道当前内容分页的总页数,由数据总条数和每页显示记录得到
3.分页需要知道当前分页内容的路径,在点击其他页码的链接有用
4.分页的显示需要知道当前页面,方便上一页和下一页的点击链接
5.需要一个变量可以限制显示每一页记录内容
分析:
1.当当前页为第一页时,首页和上一页就不需要了,当当前页为最后一页时,尾页和下一页也不需要,所以可以直接把上一页和首页放在一起,当当前页不是第一页时显示,把下一页和尾页放在一起,当当前页不是最后一页时显示。
2.当规定的每页要显示的页码数比总页数还多时,显示所有的页码数
3.例:当一共有10页,每页显示5个页码时,如果当前页是1,2,3时,那显示的第一个页码是1,当当前页是8,9,10时,显示的页码第一个页码是6,其他情况下显示的第一个页码是当前页-2,结尾页是当前页+4
height = $height; $this->width = $width; $this->strlen = $strlen; } private function creatBg() { $this->image = imagecreatetruecolor($this->width,$this->height); $color = imagecolorallocate($this->image, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255)); imagefill($this->image, 0, 0, $color); } private function creatCode() { $len = strlen($this->charset)-1; for( $i=0;$i<$this->strlen;$i++ ) { $this->code .= $this->charset[mt_rand(0,$len)]; } } private function addCode() { $x = $this->width/$this->strlen; for( $i=0;$i<$this->strlen;$i++ ) { $color = imagecolorallocate($this->image, mt_rand(0, 157), mt_rand(0, 157), mt_rand(0, 157)); imagestring($this->image, 5, $x*$i+5, 8, $this->code[$i], $color); } } private function addLine() { for( $i=0;$i<3;$i++) { $color = imagecolorallocate($this->image,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156)); imageline($this->image, mt_rand(1,$this->width/2), mt_rand(1, $this->height), mt_rand($this->width/2,$this->width), mt_rand(1, $this->height), $color); } for( $i=0;$i<50;$i++) { $color = imagecolorallocate($this->image,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156)); imagestring($this->image, 1, mt_rand(0, $this->width), mt_rand(0, $this->height), '.', $color); } } private function outImg() { imagepng($this->image); imagedestroy($this->image); } public function getCode() { $this->creatBg(); $this->creatCode(); $this->addLine(); $this->addCode(); $this->outImg(); } }
注:要实现验证码点击刷新功能
1.验证码类中增加获取验证码的方法(不区分大小写)
2.调用方法获得验证码保存到session中
3.在使用session之前必须要开始session
1.验证用户名长度
2.验证密码长度
3.验证验证码长度
4.验证验证码是否正确
5.验证账号密码是否正确
6.注:增加语句:$show = true,是表示如果输入不是add或者delete或者update,都默认的是管理员列表页面
1.admin,top,main页面需要检测
2.manage页面也需要,但是当action=login时不需要,所以要分开写
3.level所有页面都需要检测,所以可以放在构造函数中
注意:对登陆次数的修改要特殊处理
注意:
1.调用分页类只需要传入记录总条数即可
2.在分页类中将分页的限制(limit)保存到Model基类的字段中
3.Model的子类(管理员和级别)直接就可以调用$this->limit.
1.在page方法中注入一个变量
2.修改解析foreach标签,使得内部可以进行加法运算
3.在模板类中修改编号的显示,因为要进行运算,所以采用js代码
1.增加的时候要返回到最后一页,这样用户可以看到新增加的记录(返回连接为page=-1,定义获取的页码为负数时显示最后一页),当然也可以在显示列表的时候倒序排序。
2.删除成功返回到上一页
3修改成功之后返回到修改页面的上一页,可以在进入修改页面之前将修改页面的上一页保存起来,然后在通过POST获取
1.新建表格cms_nav
2.在sidebarn.html文件中修改添加导航链接
3.新建nav.php,NavAction.class.php,admin_nav.js,NavModel.class.php,nav.tpl五个文件,内容都有相应的等级文件中复制粘贴过来
4.将上面四个文件中的Level全部修改为Nav,level全部修改为nav,‘等级’全部修改为‘导航’
5.与等级不同的是,在删除等级时是要检查该等级下是否有管理员,而删除导航之前要检查该导航下面是否有子导航
6.优化列表的显示,当没有记录的时候不显示分页,提示没有记录(导航页面,管理员页面和等级页面都要修改)
注意:SHOW TABLE STATUS LIKE ‘table’,table一定要加引号!!!
1.将查询多条记录,查询单条记录,查询记录总条数,查询增加记录ID中相同的代码分离出来
2.将增加记录,删除记录,修改记录中相同的代码分离出来
1.nav.tpl添加showchild和addchild模块(复制show和add模块),addchild模块和add模块都要添加一个隐藏域名,用来存放pid,show模块要添加一列增加和查看子导航的入口
2.修改导航,增加子导航,子导航列表都要增加修改导航增加子导航和子导航列表的入口
3.NavAction.class.php文件中也要添加showchild和addchild模块
4.修改增加导航函数add,使得也适用于增加子导航
5.修改导航列表函数show,使得也适用于查看子导航(添加条件,通过pid查看)
6.修改导航,子导航列表和增加子导航模板文件中有相同的入口,可以优化一下
7.当修改导航,增加子导航,查看子导航列表时,如果不是从主页进入获取的id然后传id过去,而是字节在url中收入输入id,那我们就需要检查id是否有效
8.同样关于修改管理员等级之前也需要增加验证
9.既然考虑到我们可能直接手动在url中输入网址,那我们的上一页内容就有可能获取不到,所以我们需要处理,当上一页url获取不到时,设置为空
10.优化增加子导航和子导航列表,增加显示上级导航
1.新建LoginAction.class,php,采用ManageAction.class.php中登陆和退出的方法,将检查session放在login方法之前
action(); $this->_tpl->display(); } //业务流程控制器 private function action() { $_GET['action']= isset($_GET['action']) ? $_GET['action'] : 'login'; switch($_GET['action']) { case 'login': self::login(); break; case 'loginout': self::loginout(); break; default: break; } } //退出登陆 private function loginout() { Tool::unSession(); Tool::alertLocation('退出成功!', 'login.php'); } //验证登陆 private function login() { if(isset($_SESSION['login'])) Tool::alertLocation('已登陆成功,点击确定自动为您跳转到主页!', 'admin.php'); if(isset($_POST['send']) && $_POST['send']=='登录') { Validate::checkLength($_POST['username'],2,20,'用户名必须在2到20位之间!'); Validate::checkLength($_POST['password'],6,null,'密码不得小于6位!'); Validate::checkLength($_POST['code'], 4, 4,'验证码必须为4位!'); Validate::checkEquals(strtolower($_POST['code']), $_SESSION['code'], '验证码不正确!'); if(!!$name = $this->_model->getLoginManage('username,name','username=? and password=?',array($_POST['username'],$_POST['password']))) { $_SESSION['login']['username'] = $name->username; $_SESSION['login']['level'] = $name->name; $this->_model->setManage($name->username); Tool::alertLocation($_POST['username'].'恭喜你,登陆成功!', 'admin.php'); } else { Tool::alertBack('用户名或者密码错误!'); } } } }
2.修改login.php文件3.删除Manage.class,php文件中login和loginout相关的删除,将验证session代码放在构造函数中
4.修改top.tpl和login.tpl。将manage.php修改为login.php
1.将缓存配置文件cache.inc.php修改为common.inc.php,然后修改在init.inc.php中引入文件时文件的名字,因为我们在common.inc.php文件中可能会用到$_tpl对象,所以我们要放在实例化对象的后面引入
2.在NavAction.class.php中增加前台显示主导航的方法(必须是共有方法),因为前台只需要id和name就可以了,所以需要修改控制器中的方法,将查询字段作为参数
3.显示导航并且点击导航可以进入相应的列表页面(点击首页进入主页,即index.php)
4.前台实例化NavAction对象调用frontshow方法,可以增加显示的条数(定义常量)
1.查询导航结果要显示字段sort并且按字段sort排序
2.nav.tpl后台页面显示要添加sort,除了要显示排序,还有实现重新排序的功能,所以要添加form表单,注意:除了要提交新的排序还需要一个隐藏字段保存原本的排序,方便以后判断要不要更新排序
3.添加修改排序模块,更新修改导航的方法
1.列表页不设计某一个固定的model,所以修改Action.class.php构造函数,model参数不提供时默认为null
2.列表页显示导航和子导航
3.用js来动态显示当前列表页是的导航是什么(字体为红色)
4.当列表页是二级导航时,导航名字前面显示父级导航
5.如果想要正确显示,需要修改对变量的解析,也可以解析变量对象(同foreach中的对象)
6.既然我们可以解析对象变量,那我们在修改记录的时候直接传递对象就可以了,没必要将对象中的每个字段都分别取出保存成变量传递
、7.将网址参数传到文件名,生成不同的编译和缓存文件(如果没有参数,那么所有的缓存文件将都是一个,不会切换)
1.点击查看文档列表进入文章列表页
2.新建content.php,content.tpl,ContentAction.class,php,ContentMdel.class.php文件,内容先复制之前的导航相应的文件,然后把文中所以的导航都修改为文档,Nav修改为Content,nav修改为content。还要新建admin_content.js直接复制admin_nav前面的代码即可。
3.修改content.tpl文件,删除原本增删改查的内容,重新修改增加文档的内容
增加文档页面
4.嵌入ckeditor在线编辑器(网上下载,复制粘贴到项目根目录下),然后修改content.tpl,然后删除不相关的内容。
1.粗略增加文件上传模块(注意:文件路径!)
2.修改文件上传类,验证上传文件
3.验证成功之后开始上传(上传之前要生成一个上传文件的路径)要创建一个函数返回图片的链接路径
4.将路径返回给表单,显示图片
5.处理文件过大导致数据丢失的情况
6.ckeditor编辑器上传图片
1)删除图像信息预览中的默认内容
打开ckeditor/plugins/image/dialogs/image.js文件,搜索“b.config.image_previewText”,(b.config.image_previewText||'')单引号中的内容全删了
2)默认没有上传功能,所以我们需要手动开启上传功能
在ckeditor/config.js中配置中加入:config.filebrowserImageUploadUrl = '../config/ckeup.php?type=img';"ckeup.php"是请求的URL,也就是点击这个按钮就会post到ckeup.php文件进行处理,可以自定义文件名字
3)创建一个ckeup.php文件,用于接收上传,并且通过系统自定义的JS回调,把图片存放如编辑器中。
window.parent.CKEDITOR.tools.callFunction(CKEditorFuncNum,图片路径,返回信息);