文章目录
- 前台首页
- 注册页面
- 登陆页面
- 资料页面
- 搜索页面
- 详情页面展示
- 收藏功能
- 点赞功能
- 留言功能
- 退出功能
- 收藏夹页面
- 底部信息页面
- 其他
前台首页
当用户从浏览器输入wwww.art.demo.com
网址输入网址,点击回车后,默认是请求访问的是项目目录的index.php
的文件中内容,然后会引入到Front
的前台应用中默认会进入IndexController.class.php
的控制器中,进而读取解index函数直至返回首页返回给浏览器。
index.php
文件
<?php
if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !');
// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define('APP_DEBUG',True);
// 定义应用目录
define('APP_PATH','./Application/');
define('BIND_MODULE','Front');
// 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php';
IndexController.class.php ->index方法
public function index(){
//分页功能 每页显示六个信息
$num=6;
//筛选没有删除的
$data['is_delete']=0;
//查询满足要求的总记录数
$blog_count=$this->blog_model->where($data)->count();
//实例化分页类 传入总记录数和每页显示的记录数(25)
$page=new Page($blog_count,$num);
//分页显示输出
$show=$page->show();
//变量输出
$this->assign("show",$show);
// 赋值分页输出
$limit=$page->firstRow.','.$page->listRows;
//赋值数据集
$blog_index=$this->blog_model->order('add_time desc')->limit($limit)->where($data)->select();
//变量输出
//在控制器中我们给模板变量赋值
$this->assign('blog_index',$blog_index);
//模板渲染输出,
//不带任何参数 自动定位当前操作的模板文件
$this->display();
}
注册页面
当用户点击首页左上方的注册按钮时,页面会跳转到PersonController.class.php
控制器中的 register方法
中,返回给一个register.html
的页面如下。会看到用户注册时需要填的表单。在表单的校验方面,我分成两方面校验:一是前端校验、二是后端校验。前端校验是更友好的提示用户,提升网站的友好性。而后端的校验是防止个别用户绕过前端代码进行非法注册,提高网站的安全性。同时为了解决页面请求响应式阻塞,影响用户体验这个问题,于是采用了ajax的
异步请求技术,以通过此手段实现页面的局部更新,用来提示用户名是否可用。
HTML部分代码
<div class="login-left">
<label class="username">用户名</label>
<input type="text" value="" onkeyup="checkName();" id="username" name="username" required placeholder="用户名字" class="yhmiput" >
<label id="myres" style="border-width: 0;color: red;margin-left: 5%;"></label>
</div>
Ajax部分JavaScript代码
<script type="text/javascript">
//第一步---------------------创建ajax引擎
function getXmlHttpObject(){
var xmlHttpRequest;
//不同的浏览器获取对象xmlhttprequest 对象方法不一样
if(window.ActiveXObject){
xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");//这个是ie内核
}else{
xmlHttpRequest=new XMLHttpRequest();//非ie内核
}
return xmlHttpRequest;//将创建创建的ajax引擎实例化
}
var myXmlHttpRequest="";//设置全局变量 为了后面的chuli 函数需要取得属性
//验证用户名是否存在
function checkName(){
myXmlHttpRequest=getXmlHttpObject();//从实例化的模型里面的方法函数
if(myXmlHttpRequest){
var url="{:U('Person/do_register1')}";//url 属性 选择提交的地址
var data="username="+$('username').value;//数据 取得数据
myXmlHttpRequest.open("post",url,true);//这里选择提交的方式post
myXmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//打开请求.
//指定为了第四步处理做准备回调函数.chuli是函数名
myXmlHttpRequest.onreadystatechange=chuli;
//第二步 --------------------------发送数据到服务器端
myXmlHttpRequest.send(data);
}
}
//回调函数
function chuli(){
//第四步------------------------------取出页面返回的数据
if(myXmlHttpRequest.readyState==4){
var mes=myXmlHttpRequest.responseText;//获取json的值
//打印出来是'{"message":"该用户不能用,已经注册"}';
var mes_obj=eval("("+mes+")");//实例化对象获得mes_obj对象 message作为对象里面的属性即可调用
$('myres').innerHTML=mes_obj.message;
}
}
</script>
服务器端PHP部分代码
public function do_register1(){
//第三步-------------------------------------数据库处理
$map['username']=I('post.username');
$res=$this->person_model->where($map)->count();
//返还数据到ajax引擎里面
$notice="";
if($res>0){
$notice='{"message":"该用户名已经被注册!"}';
}else{
$notice='{"message":"该用户名可以使用!"}';
}
echo $notice;
}
当前台注册校验成功在的时候,注册信息会提交给后台do_register。如下:
public function do_register(){
$data['username']=I('post.username');//接收用户名
$data['nick']=I('post.nick');//接受用户昵称
$data['password']=md5(I('post.password'));//接受密码并且加密
$repassword=md5(I('post.repassword'));//二次接收密码
if($repassword!= $data['password']) {//判断密码是否相同
$this->error("密码不同");exit;
}
if(!trim($data['username'])) {//用户名是或否为空
$this->error("用户名字不能为空");exit;
}
if(!trim($data['nick'])) {//用户昵称是否为空
$this->error("用户昵称不能为空");exit;
}
if(!trim($data['password'])) {//用户密码是否为空
$this->error("用户密码不能为空");exit;
}
$map['username']=$data['username'];//判断用户名是否存在
$res=$this->person_model->where($map)->count();
if($res>0){
$this->error("用户名已经注册");exit;
}
$data['ip'] = get_client_ip();//获取用户的登陆ip地址
$data['add_time']=time();//获取当前用户创建的时间
$res=$this->person_model->add($data);//添加用户
if($res) $this->success("注册成功",U('/Person/login'));
}
当用户名存在的时候时,会有提示。如下图:
登陆页面
根据用户输入的用户名和密码校验数据库中的用户名和密码从而判断是否相同,若相同则存入到session中
do_login 部分代码
public function do_login(){
$data['username']=I('post.username');//获取用户名
$data['password']=md5(I('post.password'));//获取密码
if(!trim($data['username'])) {
$this->error("用户名字不能为空");exit;
}
if(!trim($data['password'])) {
$this->error("用户密码不能为空");exit;
}
$map['username']=$data['username'];
$res=$this->person_model->where($map)->count(); //查询用户名
if($res>0)
{
$user=$this->person_model->where($map)->find();
if($user['password']!=$data['password'])
{
$this->error("用户名密码不匹配");exit;
}elseif($user['is_forbid']==1)
{
$this->error("用户已经被封,请联系管理员");exit;
}else {
session('user', $user);//校验成功存入session中
$this->success("登录成功",U('/Person/info'));
}
}else{
$this->error("用户名不存在");exit;
}
如下图:
资料页面
当登陆成功了,上面的状态栏就会改变,多出了一个退出,收藏夹和资料
设置,进入个人资料中心,可以进行密码,昵称,头像的修改等操作,浏览器显示如图:
public function do_info(){
$data['nick']=I('post.nick');//接收昵称
$data['email']=I('post.email');//接收邮箱
$data['password']=md5(I('post.password'));//接收密码
if(!trim($data['nick'])) {
$this->error("用户昵称不能为空");exit;
}
if(!trim($data['email'])) {
$this->error("用户email不能为空");exit;
}
if(!trim($data['password'])) {
$this->error("用户密码不能为空");exit;
}
if (is_uploaded_file ( $_FILES ['img'] ['tmp_name'] )) {//接收头像
$icon = $_FILES ['img'];
$iconPath = "Public/images/face/" . time () . $icon ['name'];
$data ["face"] ="/blog/$iconPath";
$data_m["face"]="/blog/$iconPath";
move_uploaded_file ( $icon ['tmp_name'], $iconPath );
}
$map['id']=I('post.id');//获取id
//获取id-用来关联留言数据表中数据保持数据的一致性
$data_m['nick']=$data['nick'];
$map_m['uid']=I('post.id');
$res=$this->person_model->where($map)->save($data);
$res_m=$this->message_model->where($map_m)->save($data_m);//保持message和person表保持一致
if($res){
if($res_m){
$this->success("修改成功,正在跳转...",U('/Index/index'));
}else{
$this->error("修改失败,正在跳转...");
}
}else{
$this->error("修改失败,正在跳转...");
}
}
搜索页面
搜索功能是用来两种方式来操作,第一种是通过与js的ajax和后台的searchbox
进行异步交互,是用户在使用搜索功能的时候,输入关键字的时候,就可以直接得出候选结果,无需使用回车键进行操作。第二种就是日常的前台通过from表单提交给后台的搜索函数进行搜索,因为考虑到ajax的使用的时候对网络的要求比较高所以,为了在网络不好的情况下也要保证功能的正常使用,所以,也就保留了第二种通用的搜索习惯。搜索界面如图11所示:
SearchController中的部分代码
public function index(){
$keywords=I("get.keywords");//获取关键字
if(!empty($keywords)){//如果存在数据库中
$map['title']=array('like',"%".$keywords."%");//读取数据集其实就是获取数据表中的多行记录(以及关联数据)
$blog_list=$this->blog_model->where($map)->field('id,title,add_time as cTime,img ,subtitle')->order('add_time desc')->select();
//数据进行加工处理
foreach($blog_list as $k=>$v){
$blog_list[$k]['img']= "http://".$_SERVER["SERVER_NAME"].$v['img'];
$blog_list[$k]['cTime']=date('Y-m-d H:i:s', $v['cTime']);
}
$this->assign("blog_list",$blog_list);
}
$this->display();
}
详情页面展示
通过get提交的id参数,然后经过数据的比对,再把数据返回给客户端。详情界面如图
public function index(){
$map['is_delete']=0;
$list=$this->cat_model->get_all_cat($map,10000);
$this->assign('list',$list);
$map['id']=I("get.id");
//取出文章
$detail=$this->blog_model->field('id,title,pv,author,update_time,add_time,img,zan,content')->where($map)->find();
// 点击率增加
$detail['pv']=$detail['pv']+1;
$res=$this->blog_model->where($map)->save($detail);
//图片储存地址转化
$detail['img']= "http://".$_SERVER["SERVER_NAME"].$detail['img'];
$this->assign("detail",$detail);
// 取出文章留言
$map1['bid']=I("get.id");
$message=$this->message_model->where($map1)->select();
$this->assign("message",$message);
//设置收藏权限必须登录
$user=session('user');
if($user!=null){
$map2['bid']=I("get.id");
$map2['uid']=$user['id'];
if($this->collettion_model->where($map2)->count()){
$this->assign("is_c",1);
}
}
$this->display();
}
收藏功能
<if condition="$is_c eq null">
<li class="btn"><a href="javascript:;" id="{$detail.id}"
class="btn btn-sm-white collection" style="margin-left:8px;"> <span>收藏</span></a></li>
<else/>
<li class="btn"><a href="javascript:;" id="{$detail.id}"
class="btn btn-sm-white collection" style="margin-left:8px;"> <span>已收藏</span></a></li>
</if>
<script type="text/javascript">
//收藏功能ajax 的交互式
$(".collection").on('click',function(){
var Oa=$(this);
var id=Oa.attr('id');//获取id属性
var vl=Oa.find("span").text();
vl=parseInt(vl)+1;
$.post('__CONTROLLER__/collection',{id:id},function(data){
if(data.status==1){
// alert('感谢您的支持!');//模拟异步数据加1
Oa.find("span").text("已收藏");//页面元素加1
}else{
alert('您已经收藏,不要重复哦!');
}
},'json');
})
</script>
public function collection(){
$user=session('user');//获取session里面的user值
if($user==null){//判断是否为空
$this->error("请先登录",U('/Person/login'));exit;
}
$data['uid']=$user['id'];//获取session的id
$data['bid']=I('post.id');//获取工艺品详情页的id
if($this->collettion_model->where($data)->count()){//数据库校验判断是否已经存在
$data['info'] = "fail";
$data['status'] = 0;
$this->ajaxReturn($data);
exit();
}else{
if($this->collettion_model->add($data)){//是否存在数据库中,则插入到数据库
$data['info'] = "ok";
$data['status'] = 1;
$this->ajaxReturn($data);
exit();
}else{//没有插入成功的话就返回错误信息
$data['info'] = "fail";
$data['status'] = 0;
$this->ajaxReturn($data);
exit();
}
}
}
点赞功能
<li class="login-sub" style="list-style-type:none;" class="btn"><a class="zan" id="{$detail.id}" style="text-decoration:none;" href="javascript:void(0);" class="btn btn-sm-white" style="margin-left:8px;">span>{$detail.zan}</span></a></li>
<script type="text/javascript">
//点赞功能ajax 的交互式
$(".zan").on('click',function(){
var Oa=$(this);
var id=Oa.attr('id');//获取id属性
var vl=Oa.find("span").text();
vl=parseInt(vl)+1;
$.post('__CONTROLLER__/zan',{id:id},function(data){
if(data.status==1){
//模拟异步数据加1
Oa.find("span").text(vl);//页面元素加1
}else{
alert('您已经点过赞了,不要重复哦!');
}
},'json');
})
</script>
public function zan(){
$data['id']=isset($_POST['id'])?intval(trim($_POST['id'])):0;
$obj = M("Art");
if(!isset($_COOKIE[$_POST['id']+10000])&&$obj->where($data)->setInc('zan')){
$cookiename = $_POST['id']+10000;
setcookie($cookiename,40,time()+60,'/');
$data['info'] = "ok";
$data['status'] = 1;
$this->ajaxReturn($data);
exit();
}else{
$data['info'] = "fail";
$data['status'] = 0;
$this->ajaxReturn($data);
exit();
}
}
留言功能
<form action="{:U('Detail/message')}" method="post">
<textarea name="content" name="content" placeholder="你的留言" required=""></textarea>
<input type="hidden" value="{$detail.id}" name="bid">
<input type="submit" value="提交" >
</form>
public function message(){
$user=session('user');
if($user==null){
$this->error("请先登录",U('/Person/login'));exit;
}
//对留言信息做出获取
$data['uid']=$user['id'];
$data['face']=$user['face'];
$data['nick']=$user['nick'];
$data['bid']=I('post.bid');
$data['content']=I('post.content');
$data['ip'] = get_client_ip();
$data['add_time']=time();
$res=$this->message_model->add($data);
if($res){
$this->success('添加成功');
}else{
$this->error('添加失败');
}
}
退出功能
public function quit(){
session('user', null);
$this->success("注销成功",U('/Index/index'));
}
收藏夹页面
<div class="btn">
<a href="{:U('/Detail/index/id/'.$v['id'])}" class="edit">查看</a>
<a href="javascript:;" id="{$v.id}" class="del"><span>删除</span></a>
</div>
public function collection(){
$user=session('user');
if($user==null){
$this->error("请先登录",U('/Person/login'));exit;
}
$data['uid']=$user['id'];
$data['is_delete']=0;
$id=$this->collettion_model->where($data)->getField('bid',10000);
$map['id']=array('in',$id);
$blog_index=$this->blog_model->where($map)->select();
$this->assign('blog_index',$blog_index);
$this->display();
}
public function del_coll(){
$user=session('user');
if($user==null){
$this->error("请先登录",U('/Person/login'));exit;
}else{
$data['bid']=isset($_POST['id'])?intval(trim($_POST['id'])):0;
$obj = M("Collection");
$map['is_delete']=1;
if($obj->where($data)->save($map)){
$data['info'] = "ok";
$data['status'] = 1;
$this->ajaxReturn($data);
exit();
}else{
$data['info'] = "fail";
$data['status'] = 0;
$this->ajaxReturn($data);
exit();
}
}
}
底部信息页面
function _initialize(){
//底部备案信息
$this->config_model=D('Config');
$config=$this->config_model->limit(1)->order('id asc')->field('icp,email')->find();
$this->assign('config',$config);
}