前面写了一篇ThinkPHP简单应用的博客,主要是熟悉一下ThinkPHP框架自动生成的各文件的作用,所以只用到了一个模块(即Index模块),一个完整的项目肯定不只一个模块(一个模块对应一个XxxAction.class.php文件,如果一个大的项目只有一个模块,那这个php文件该写多长啊),而且前一篇博客ThinkPHP自动生成的文件简便起见我放在了项目根目录下,显得不大规范。同时为了使ThinkPHP功能更完善,这里使用的版本为PHP5.3+ThinkpHP3.2.1,自动生成的目录和前面的ThinkPHP2.0会有些细微的差别。下面就以一个小型的聊天系统为例写一个规范一点的ThinkPHP应用工程。仅作自己学习笔记使用,如有不当的地方,请大神赐教。
一、准备工作:
1.
在官网上下载ThinkPHP3.2,解压后目录如下:
2.建立数据库think,在think中think_login表:
再建立一个think_friend表:
3.在Zend Studio中建立MyThinkPHP工程,将下载的ThinkPHP解压后复制到工程目录下。
运行自带的index.php出现如下欢迎界面:
此时再看一下工程目录,Application目录下的所有文件(Common,Home,Runtime)均为ThinkPHP自动生成的:
4.找到系统配置文件config.php,可以发现在Common/Conf目录下,在config.php中完成数据库的配置:
<?php
return array(
'APP_DEBUG'=>false,
'DB_TYPE'=>'mysql',
'DB_HOST'=>'localhost',
'DB_NAME'=>'think',
'DB_USER'=>'root',
'DB_PWD'=>'wtyy',
'DB_PORT'=>'3306',
'DB_PREFIX'=>'think_' //数据表的前缀
);
?>
二、实现注册登录:
1.
(1)找到控制器,可以发现在Home/Contorller目录下,有一个系统默认的Index控制器,即IndexController.class.php,打开里面是这样的
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
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'>^_^ Hello,娆㈣繋浣跨敤<span style='font-weight:bold;color:red'>ThinkPHP</span></div>";
}
}
我们重新编写这个方法,实现登录功能:
<?php
// 鏈被鐢辩郴缁熻嚜鍔ㄧ敓鎴愶紝浠呬緵娴嬭瘯鐢ㄩ�
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
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'>^_^ Hello,娆㈣繋浣跨敤<span style='font-weight:bold;color:red'>ThinkPHP</span></div>";
if(isset($_POST['sub'])){
$name=$_POST['name'];
$pwd=$_POST['pwd'];
if($name=="" || $pwd==""){
echo "<script>alert('信息不可以为空')</script>";
}else{
$db=M();
$res=$db->query("select pwd from think_login where name='$name'");
$arr=$res[0]['pwd'];
if($arr==$pwd){
/*session_start();
$_SESSION['name']=$name;*/
session('[start]');
session('name', $name);
echo "<script>alert('登录成功')</script>".session('name');
//$this->display('Add:add');
//R("Add","add","App");
$this->redirect('Add/add');
//echo "<script>window.location.href='__TMPL__/Main/all'</script>";
}else{
echo "<script>alert('用户名或密码错误')</script>";
}
}
}
else
$this->display();
}
}
(2)定位到Home/View目录,创建Index模板文件夹,在Index文件夹下编写index方法对应的模板index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div style="position:absolute">
<img src="__ROOT__/Public/images/1.png" width="100%" height="100%">
<!-- <div style="position:absolute;top:10%;right:0">-->
<form action="__URL__/index" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" id="name" name="name"></td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" id="pwd" name="pwd"></td>
</tr>
<tr>
<td><input type="submit" name="sub" id="sub" value="登录"></td>
<td><a href="__URL__/login">注册</a></td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
2.下面完成注册功能:
(1)在index控制器中编写login方法,此时Index控制器完整代码如下:
<?php
// 鏈被鐢辩郴缁熻嚜鍔ㄧ敓鎴愶紝浠呬緵娴嬭瘯鐢ㄩ�
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
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'>^_^ Hello,娆㈣繋浣跨敤<span style='font-weight:bold;color:red'>ThinkPHP</span></div>";
if(isset($_POST['sub'])){
$name=$_POST['name'];
$pwd=$_POST['pwd'];
if($name=="" || $pwd==""){
echo "<script>alert('信息不可以为空')</script>";
}else{
$db=M();
$res=$db->query("select pwd from think_login where name='$name'");
$arr=$res[0]['pwd'];
if($arr==$pwd){
/*session_start();
$_SESSION['name']=$name;*/
session('[start]');
session('name', $name);
echo "<script>alert('登录成功')</script>".session('name');
//$this->display('Add:add');
//R("Add","add","App");
$this->redirect('Add/add');
//echo "<script>window.location.href='__TMPL__/Main/all'</script>";
}else{
echo "<script>alert('用户名或密码错误')</script>";
}
}
}
else
$this->display();
}
public function login(){
if(isset($_POST['sub'])){
$name=$_POST['name'];
$pwd=$_POST['pwd'];
if($name=="" || $pwd==""){
echo "<script>alert('信息不可以为空')</script>";
}else{
$db=M();
$res=$db->query("select name from think_login where name='$name'");
if($res!=null){
echo "<script>alert('该用户名已注册')</script>";
}else{
$da=M("login");
$da->Create();
$data['name']=$name;
$data['pwd']=$pwd;
$re=$da->add($data);
if($re)
echo "<script>alert('注册成功')</script>";
}
}
}
$this->display();
}
}
?>
(2)在Index模板文件夹下编写login.html模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="__URL__/login" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="name" id="name"></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="password" name="pwd" id="pwd"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="sub" id="sub" value="注册"></td>
</tr>
</table>
</form>
</body>
</html>
现在运行入口文件index.php,界面是这样的:
点击注册按钮注册一个帐号之后再登录,
三、实现添加好友:
再在View下建立Add模板文件夹,作为好友模块,同时在Controller下建立对应的AddController.class.php控制器。
1.(1)在Add模板文件夹下建立add.html模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table width="100%">
<tr>
<td width="33%">
<a href="__URL__/add">添加好友</a></td>
<td width="33%">
<a href="__URL__/newfr">新朋友</a></td>
<td width="33%">
<a href="__URL__/chat">好友聊天</a></td>
</tr>
</table>
<br>
<br>
<center>
<form action="__URL__/add" method="post">
<input type="text" name="name" id="name">
<input type="submit" id="sub" name="sub" value="搜索">
</form>
<a href="__URL__/addfr?id={$fr}">{$fr}</a>
</center>
</body>
</html>
(2)在Add控制器中编写add方法,查找输入的帐号是否存在:
<?php
// 閺堫剛琚悽杈╅兇缂佺喕鍤滈崝銊ф晸閹存劧绱濇禒鍛返濞村鐦悽銊╋拷
namespace Home\Controller;
use Think\Controller;
class AddController extends Controller {
public function add(){
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'>^_^ Hello,濞嗐垼绻嬫担璺ㄦ暏<span style='font-weight:bold;color:red'>ThinkPHP</span></div>";
if(isset($_POST['sub'])){
$name=$_POST['name'];
$db=M();
$res=$db->query("select name from think_login where name='$name'");
if($res!=null){
$fr=$name;
}else{
$fr="";
echo "<script>alert('该人不存在')</script>";
}
}
$this->assign("fr",$fr);
$this->display();
}
}
存在的话,输出该人用户名,点击该用户名链接跳转至addfr.html
2.
(1)在Add模板文件夹下编写addfr.html模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
{$me}请求添加{$fr}为好友<br>
<form action="" method="post">
<textarea id="qq" name="qq"></textarea>
<input type="submit" id="sub" name="sub" value="发送验证消息">
</form>
</body>
</html>
(2)在Add控制器中编写addfr方法:
public function addfr(){
header("Content-Type:text/html; charset=utf-8");
$fr=$_GET['id'];//对方
//session_start();
$me=session('name');//我
if(isset($_POST['sub'])){
$qq=$_POST['qq'];
$dba=M('friend');
$dba->Create();
$data['flag']="0";//还不是好友
$data['applyor']=$fr;//被申请人
$data['me']=$me;
$data['qq']=$qq;
$dba->add($data);
}
$this->assign("me",$me);
$this->assign("fr",$fr);
$this->display();
}
3.
(1)在Add控制器中编写newfr方法,查询所有申请者:
public function newfr(){
$me=session('name');//我
$db=M('friend');
//$app=$db->distinct(true)->where("applyor='$me' and flag='0'")->select();
$app=$db->distinct(true)->field('me')->where("applyor='$me' and flag='0'")->select(); //去重复查询me
$this->assign("app",$app);
$this->display("newfr");
}
(2)在Add模板文件夹下编写对应的newfr.html模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<volist name="app" id="friend">
<a href="__URL__/addnew?id={$friend.me}">{$friend.me}</a> <br>
</volist>
</body>
</html>
4.(1)再在Add模板文件夹中编写addnew.html模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
跳转中
</body>
</html>
(2)在Add控制器中编写对应的addnew方法,作为中转界面,这个中转页的作用是接收get请求传来的参数并存下来:
public function addnew(){//同意申请的中转页
$fr=$_GET['id'];//对方
session('fr',$fr);
$this->redirect("Add/addnew1");
}
5.来看addnew1.HTML模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
{$me}添加{$fr}为好友
<form action="__URL__/addnew1" method="post">
<input type="submit" value="同意" name="sub" id="sub">
</form>
</body>
</html>
对应的addnew1方法:
public function addnew1(){
$fr=session('fr');
$me=session('name');//我
if(isset($_POST['sub'])){
$db=M('friend');
$data['flag']="1";//为好友
$a=$db->where("applyor='$me' and flag='0' and me='$fr'")->save($data);
if($a>0)
echo "<script>alert('添加好友成功')</script>";
}
$this->assign("me",$me);
$this->assign("fr",$fr);
$this->display("addnew1");
}
注意这里的addnew中转页,初学者可能会问既然中转页中已经取得了get传来的id,为什么不可以把addnew1中的form表单放到addnew中,即去掉这个addnew中转页。这样是不可以的,因为form表单会再次请求本页(addnew1方法再次执行),这时候get传来的值是空的了。
四、实现聊天功能:建立Fr控制器,并创建对应的Fr模板文件夹。
前面我们给的”好友聊天“链接的地址为add/chat.html,现在我们在Add控制器的chat方法中将这个链接重定向到Fr控制器:
public function chat(){
$this->redirect("Fr/fr");
}
1.(1)在Fr控制器中编写fr方法,查询所有好友:
public function fr(){
header("Content-Type:text/html; charset=utf-8");
$me=session('name');//我
$db=M('friend');
//$app=$db->distinct(true)->where("applyor='$me' and flag='0'")->select();
$app=$db->distinct(true)->field('me')->where("applyor='$me' and flag='1'")->select(); //去重复查询me
$this->assign("app",$app);
$this->display("fr");
}
(2)在Fr模板文件夹下编写对应的fr.html模板文件,输出所有好友:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<volist name="app" id="friend">
<a href="__URL__/deal?id={$friend.me}">{$friend.me}</a> <br>
</volist>
</body>
</html>
跟之前一样,点击链接跳转至中转页deal.html,Fr控制器中的中转处理方法为:
public function deal(){//好友聊天的中转页
$fr=$_GET['id'];//对方
session('friend',$fr);
$this->redirect("Fr/chat");
}
2.(1)再在Fr模板文件夹下创建chat.html模板文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
{$friend}<br>
<volist name="qq" id="friend">
{$friend.qq}<br>
</volist>
<form action="__URL__/chat" method="post">
<textarea rows="" cols="" name="msg" id="msg"></textarea>
<input type="submit" name="sub" id="sub" value="发送">
</form>
</center>
</body>
</html>
(2)在Fr控制器中编写对应的chat方法:
public function chat(){
header("Content-Type:text/html; charset=utf-8");
$me=session('name');//我
$friend=session('friend');
$db=M('friend');
$qq=$db->where("flag='1' and me='$me' and applyor='$friend'")->select();
if(isset($_POST['sub'])){
$msg=$_POST['msg'];
$db->Create();
$data['flag']="1";
$data['applyor']=$friend;
$data['me']=$me;
$data['qq']=$me.":".$msg;
$a=$db->add($data);
$data1['flag']="1";
$data1['applyor']=$me;
$data1['me']=$friend;
$data1['qq']=$me.":".$msg;
$a1=$db->add($data1);
if($a>0 && $a1>0){
//echo "发送成功";
}
}
$this->assign("friend",$friend);
$this->assign("qq",$qq);
$this->display("chat");
}
来看一下最终的目录: