就以这个小实例来将核心包里的知识串一下,并且学习thinkphp3的三大自动,以及拓展包文件上传、验证码、Ajax的简单实用。不具体去做前端的样式,仅仅简单实现一下功能。
功能分析
登录模块,加图片
注册模块,加图片
留言模块,加图片
数据库设计
根据下表建立数据库
to_user (用户表) |
|
|
|
|
|
字段 |
类型 |
notnull |
默认值 |
备注 |
|
id |
int |
notnull |
|
主键 自增 |
|
username |
varchar(30) |
‘’ |
用户名 |
|
|
password |
char(32) |
|
|
密码 |
|
sex |
tyint |
notnull |
1 |
性别:1代表男 0 代表女 |
|
|
|
|
|
|
|
tp_message |
|
|
|
|
|
字段 |
类型 |
notnull |
默认值 |
备注 |
|
id |
int |
notnull |
|
主键 自增 |
|
title |
varchar(60) |
‘’ |
题目 |
|
|
content |
text |
|
|
内容 |
|
filename |
varchar(30) |
notnull |
1 |
附件名 |
|
time |
int |
|
|
时间:时间戳格式 |
|
uid |
int |
|
|
外键:用户表中的id |
|
|
|
|
|
|
|
创建项目
将thinkphp文件夹复制到新建的Message文件夹中,并且创建主入口文件index.php
1 2 3 4 5 6 7 8 9 10
| <?php
define('APP_NAME','Home');
define('APP_PATH','./Home/');
require './ThinkPHP/ThinkPHP.php'; ?>
|
保存文件后。访问http://localhost/Message/index.php就可以看到文件里自动生成了项目文件
首页功能
一个留言板的首页是怎样的呢?这里将首页切割成三份,一部分显示系统名称留言板,第二部分显示留言内容,第三部分提交留言内容。并且建立好相应的前端模板文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php class IndexAction extends Action { public function index(){ if(isset($_SESSION['username'])&&$_SESSION['username']!=''){ $this->display(); }else{ $this->redirect('Login/login'); } } public function top(){ $this->display(); } public function left(){ $this->display(); } public function right(){ $this->display(); } }
|
以上方式需要在每个需要判断session的地方加上上述代码。因此,我们可以建立一个公共的中间类,在初始化阶段就完成权限判断,不仅如此,还可以将一些公共部分添加进来。
1 2 3 4 5 6 7 8 9 10 11
| <?php class CommonAction extends Action{ Public function _initialize(){ if(!isset($_SESSION['username']) || $_SESSION['username']==''){ $this->redirect('Login/login'); } } } ?>
|
这样就需要将Index模块改写,继承Commcon
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php
class IndexAction extends CommonAction { public function index(){ $this->display(); } public function top(){ $this->display(); } public function left(){ $this->display(); } public function right(){ $this->display(); } }
|
模板部分如下,需要先建好top.html,left.html,right.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // Tpl\Index\index.html <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Index</title> </head> <frameset rows='20%,*'> <frame src='__URL__/top' name='top'/> <frameset cols='50%,50%'> <frame src='__URL__/left' name='left'/> <frame src='__URL__/right' name='right'/> </frameset> </frameset> </html>
|
登陆功能
登陆功能首先需要一个登陆页面,还要相应的模块进行登陆的验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?php
class LoginAction extends Action{ public function login(){ $this->display(); } public function doLogin(){ $username=$_POST['username']; $password=$_POST['password']; $code=$_POST['code']; if(md5($code)!=$_SESSION['code']){ $this->error('验证码不正确'); exit(); } $where['username']=$username; $where['password']=$password; $user=M('User'); $count=$user->where($where)->count(); if($count>0){ $_SESSION['username']=$username; $_SESSION['id']=$id; $this->success('登陆成功',U('Index/index')); }else{ $this->error("用户或密码错误",U('Login/login')); } } }
?>
|
验证码的使用
先下载拓展包解压会得到一个Extend文件,替换掉ThinkPHP文件里的Extend。然后再创建一个公共的验证码的模块控制器。代码如下
1 2 3 4 5 6 7 8 9
| <?php class PublicAction extends Action{ public function code(){ import('ORG.Util.Image'); Image::buildImageVerify(4,1,'png',30,30,'code'); } } ?>
|
会生产一个图片,只要在前端引用这个图片就好了。
1
| 验证码: <input type='text' name='code'/><img src='__APP__/Public/code' onclick="this.src=this.src+'?'+Math.random()"/><br/>
|
完整的Login.html代码如下,省略了图片和Css,Js文件。此处使用js来进行表单的提交。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Login</title> <load href="__PUBLIC__/Css/basic.css" /> <load href="__PUBLIC__/Css/Home/reg.css" /> <load href="__PUBLIC__/Js/jquery.js"/> <script> $(function(){ $('img[title="register"]').click(function(){ window.location.href="__APP__/Register/reg"; }); var error = new Array(); $('input[name="code"]').blur(function(){ var code = document.forms['myForm']['code'].value; $.post('__APP__/Public/Yzcode',{'code':code},function(data){ if(data=='error'){ error['code']=1; $('#code').remove(); $('img[name="code"]').after('<p id="code" style="color:red">验证码错误</p>'); }else if(data=='correct'){ error['code']=0; $('#code').remove(); } }); }); $('img[title="login"]').click(function(){ if(error['code']==0){ $('form[name="myForm"]').submit(); }else{ return false; } }); }); </script> </head> <body> <form action='__URL__/doLogin' method='post' name='myForm'> 用户名:<input type='text' name='username'/></br> 密 码:<input type='password' name='password'/><br/>
验证码: <input type='text' name='code'/><img src='__APP__/Public/code' onclick="this.src=this.src+'?'+Math.random()" name='code'/><br/> <img src='__PUBLIC__/Images/login.gif' title='login' class='submit'/> <img src='__PUBLIC__/Images/register.gif' title ='register'/> </form> </body> </html>
|
账号退出
利用thinkphp3提供的对session进行操作的方法,实现账号的退出。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public function doLogout(){
session('[destroy]'); $this->redirect('Index/index'); }
|
注册功能
注册功能和登录功能差不太多,运用Ajax来实现用户名是否已经被注册了。首先先创建好注册功能的模板文件.
为了能顺利理解和使用Ajax。。狂补了一波JS语法。。
注册页面的代码。实现了ajax判断是否注册,已经确认密码操作。应该考虑一下把js代码封装起来?之后再完善吧.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>注册</title> <load href="__PUBLIC__/Css/basic.css" /> <load href="__PUBLIC__/Css/Home/reg.css" /> <load href="__PUBLIC__/Js/jquery.js"/> <script> $(function(){ var error=new Array(); $('input[name="username"]').blur(function(){ var username = document.forms['myForm']['username'].value; $.post('__URL__/ajax',{'username':username},function(data){ if(data=='已注册'){ error['username']=1; $('#umessage').remove(); $('input[name="username"]').after('<p id="umessage" style="color:red">该用户名已经注册</p>'); }else if(data=="可以注册"){ error['username']=0; $('#umessage').remove(); } }); }); $('input[name="repassword"]').blur(function(){ var password1=document.forms['myForm']['password'].value; var password2=document.forms['myForm']['repassword'].value; if(password1==password2&&password1!=''&&password2!=''){ error['password']=0; $('#pmessage').remove(); }else{ error['password']=1; $('#pmessage').remove(); $('input[name="password"]').after('<p id="pmessage" style="color:red">两次输入的密码不一样</p>'); } }); $('input[name="code"]').blur(function(){ var code = document.forms['myForm']['code'].value; $.post('__APP__/Public/Yzcode',{'code':code},function(data){ if(data=='error'){ error['code']=1; $('#code').remove(); $('img[name="code"]').after('<p id="code" style="color:red">验证码错误</p>'); }else{ error['code']=0; $('#code').remove(); } }); }); $("img.register").click(function(){ if(error['username']==1){ return false; }else if(error['password']==1){ return false; }else if(error['code']==1){ return false; }else{ $("form[name='myForm']").submit(); } }); }); </script> </head> <body> <form action='__URL__/doReg' method='post' name='myForm'> 用 户 名:<input type='text' name='username'/><br/> 密 码:<input type='password' name='password'/><br/> 确认密码:<input type='password' name='repassword'/><br/> 性 别:<input type='radio' name='sex' value='1' class='radio'/>男 <input type='radio' name='sex' value='0' class='radio'/>女<br/> 验 证 码:<input type='text' name='code'/> <img src='__APP__/Public/code' onclick="this.src=this.src+'?'+Math.random()" name='code'/> <br/> <img src='__PUBLIC__/Images/register.gif' class='register'/> <img src='__PUBLIC__/Images/reset.gif' class='reset'/> </form> </body> </html>
|
自动创建
在实际的注册功能这,首先想到的是定义一个doReg函数来接受参数之后再进行add()插入数据。Thinkphp3提供了自动创建的功能,能够自动将传来的POST值自动创建数据对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <?php
class RegisterAction extends Action{ public function reg(){ $this->display(); } public function doReg(){
$username=$_POST['username']; $password=$_POST['password']; $sex = $_POST['sex']; $User = M('User'); $User->username=$username; $User->password=$password; $User->sex=$sex; if($User->add()>0){ $this->success("注册成功",U('Login/login')); }else{ $this->error("注册失败"); } } public function doReg2(){
$User=D('User'); if(!$User->create()){ $this->error($User->getError()); } if($User->add()>0){ $this->success("注册成功",U('Login/login')); }else{ $this->error("注册失败"); } } } ?>
|
自动验证
既然可以自动创建出数据模型,那如何对他们的数据符不符合数据库里定义的标准该如何判断?thinkphp3提供自动验证的机制,需要在模型类中定义好规则。注意上文创建模型是用D方法,D(‘User’)是将UserModel.class.php进行实例化,和M方法是完全不一样的,在实际开发,自带的Model是不足以满足业务需求,因此需要定义自己的模型类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<?php class UserModel extends Model{ protected $_validate=array( array('code','require','验证码必须填写!'), array('code','checkCode','验证码错误!',0,'callback',1), array('username','require','用户必须填写!'), array('username','','用户已经存在',0,'unique',1), array('username','/^\w{6,}$/','用户名必须6个字母以上',0,'regex',1), array('repassword','password','确认密码不正确',0,'confirm'), ); } protected function checkCode($code){ if(md5($code)!=$_SESSION['code']){ return false; }else{ return true; } }
?>
|
留言模块
留言模块实质就是将留言内容插入到数据库,以及将上传的附件名字存入数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <?php
class MessageAction extends Action{ public function doMessage(){ $title = $_POST['title']; $content = $_POST['content']; $message = new Model('Message'); $message->time=time(); $message->tittle=$title; $message->content=$content; if(!empty($_FILES['filename']['name'])&&$_FILES['filename']['name']!="") { import('ORG.Net.UploadFile'); $upload = new UploadFile(); $upload->savePath = './Public/Uploads/'; $upload->allowExts = array('jpg', 'gif', 'png', 'jpeg'); if(!$upload->upload()) { $this->error($upload->getErrorMsg()); }else{ $info = $upload->getUploadFileInfo(); $message->filename=$info[0]['savename']; } } $message->uid=$_SESSION['id']; if($message->add()){ $this->success('成功留言'); }else{ $this->error('留言失败'); } } }
?>
|
包含了文件上传的组件的最基本利用,还可以设置文件上传的后缀等安全措施。
显示留言
关联模型
关联模型可以非常方便的将两个有相互关系的表关联起来,此时自定义的模型类需要继承的是RelationModel而不是Model 详细信息参看手册。
自动完成
自动完成是三大自动之一,可以自动完成一些操作,例如将密码进行md5加密,赋值等操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php
class MessageModel extends RelationModel{ protected $_auto=array( array('time','time',1,'function'), array('uid','getId',1,'callback'), ); protected $_link = array( 'User'=> array( 'mapping_type'=>BELONGS_TO, 'class_name'=>'User', 'foreign_key'=>'uid', 'mapping_name'=>'user', 'as_fields'=>'username', ),
); protected function getId(){ echo $_SESSION['id']; return $_SESSION['id']; } }
?>
|
数据分页
在IndexAction.class.php中将数据库的值查询出,再利用分页操作,将数据分页。并且数据传递交由给模板显示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?php class IndexAction extends Action { public function index(){ if(isset($_SESSION['username'])&&$_SESSION['username']!=''){ $this->display(); }else{ $this->redirect('Login/login'); } } public function top(){ $this->display(); } public function left(){ $message=D('Message'); import('ORG.Util.Page'); $count=$message->count(); $page = new Page($count,2); $page->setConfig('header','条留言'); $show = $page->show(); $arr = $message->relation(true)->limit($page->firstRow.','.$page->listRows)->select(); $this->assign('list',$arr); $this->assign('show',$show); $this->display();
} public function right(){ $this->display(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| left.html <html> <h1>留言板</h1> <body> <foreach name='list' item='vo'> <p>留言标题:{$vo.tittle}</p> <p>留言内容:{$vo.content}</p> <p>留言用户:{$vo.uname}</p> <p>留言时间:{$vo.time|date='Y/m/d H:i:s',###}</p> <p>附 件:{$vo.filename}</p> <hr/> </foreach> {$show} </body> </html>
|
Author:
zhhhy
Permalink:
http://yoursite.com/2019/03/12/pjfortp31/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Solgan:
Do you believe in DESTINY?