陈力:传智播客古代 珍宝币 泡泡龙游戏开发第42讲:PHP数据库开发案例
上节学习了Mysql数据的操作,本节结合贵阳网站建设的实践经验,通过MVC思想进行实例开发和程序设计。
一、网站建设流程介绍
进行网站建设案例设计的主要目的是培养贵阳网站建设人员编写项目的思维,充分认识MVC模式和规划项目过程,在设计过程中融入了各个知识点[php基础、html、数据库、开发模式、cookie/session]。
本文以雇员管理系统作为案例进行详细分析,开发方式采用原型开发方式。按照需求分析->设计阶段->编码阶段->测试阶段->发布阶段/维护阶段等过程进行网站建设。
需求阶段: 需求分析是设计人员/项目经理对客户(领导)进行调研,写出需求文档。
设计阶段: 技术人员(架构师,组长,程序员)进行数据库、系统结构等设计。
开发阶段: 一般是组长或者程序员。
测试阶段: 测试人员。
发布阶段: 实施人员(实施工程师)。
维护阶段: 往往是开发人员中的成员。
设计总体步骤:一般是美工(ps画图)->网页前端人员(html)[原型] ->客户[程序员]。
二、雇员管理系统开发文档
(一)需求分析
该雇员管理系统在需求分析阶段得出的需求功能如下:
1)管理员可以登录到管理界面进行管理。
2)雇员信息增加。
3)雇员信息修改。
4)查看雇员信息,要采用分页的显示方式。
5)可以删除雇员信息。
6)实现用户在一定时间不用反复登录,可以统计网站访问的次数。
(二)画出uml时序图
采用uml(统一建模语言)进行用例分析,画出时序图。该部分略。
(三)进行界面设计
本文涉及到的主要界面如下:
登录界面:
主界面
管理员的管理界面
(四)设计数据库
请注意:对于一个大型项目而言,我们建议表的字段名可以采用表名_字段名的方式。
步骤:进入MySQL 5.5 Command Line Client,即进入MySQL命令行方式。新建名为empdb的数据库。Create database empdb; 再打开数据库,use empdb;
创建admin表和emp表。其字段内容如下:
管理员表(admin):
create table admin(
id int primary key ,
name varchar(32) not null,
password varchar(128) not null);
雇员表(emp):
create table emp(
id int primary key auto_increment,
name varchar(64) not null,
grade tinyint, /*1 表示1级工.. */
email varchar(64) not null,
salary float
)
添加初始化数据:
insert into emp (name,grade,email,salary) values('ZS',1,'zs@sohu.com',2000);
insert into emp (name,grade,email,salary) values('LS',1,'ls@163.com',3000);
insert into emp (name,grade,email,salary) values('WW',1,'ww@163.com',5000);
insert into admin values(100,'admin',md5('admin'));
(五)代码阶段
准备素材(图片、静态页面、flash、文字)等。
(六)性能要求
如果用户登录不成功,要在login.php页面显示红色的提示信息。在管理页面提供一个超链接,可以退出系统。
三、雇员管理系统开发步骤
(一)先完成简单的登录验证功能,可以不链接到数据库。
要求完成不链接数据库验证,如果登录成功则转到主页,如果不成功则给出红色提示。在管理页面提供一个超链接,可以退出系统。
login.php源码:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<h1>管理员登录系统</h1>
<form action="loginProcess.php" method="post">
<table>
<tr><td>用户id</td><td><input type="text" name="id"/></td></tr>
<tr><td>密 码</td><td><input type="password" name="password"/></td></tr>
<tr>
<td><input type="submit" value="用户登录"/></td>
<td><input type="reset" value="重现填写"/></td>
</tr>
</table>
</form>
<?php
//接收errno
if(!empty($_GET['errno'])){
//接收错误编号
$errno=$_GET['errno'];
if($errno==1){
echo "<br/><font color='red' size='3'>你的用户名或者密码错误</font>";
}
}
?>
</html>
loginProcess.php源码:
<?php
//require_once 'AdminService.class.php';
//接收用户的数据
//1.id
$id=$_POST['id'];
//2.密码
$password=$_POST['password'];
if($id=="100" && $password=="admin")
{
//合法
header("Location: empManage.php");
exit();
}
else{
//非法
header("Location: login.php ?errno=1");
exit();
}
?>
empManage.php源码:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<?php
echo "登录成功!";
echo "<br/><a href='login.php'>返回重新登录</a>";
?>
</html>
(二)链接到数据库去验证用户登录。检查该用户是否存在。
<?php
//接收用户的数据
//1.id
$id=$_POST['id'];
//2.密码
$password=$_POST['password'];
//得到链接
$conn=mysql_connect("localhost","root","123456");
if(!$conn){
die("数据库链接失败".mysql_error());
}
mysql_query("set names utf8",$conn) or die(mysql_error());
mysql_select_db("empdb",$conn) or die(mysql_error());
//防止SQL注入.
$sql="select password from admin where id=$id";
$res=mysql_query($sql,$conn);
if($row=mysql_fetch_assoc($res)){
//查询到,取数据库密码
if($row['password']==md5($password)){
header("Location: empManage.php");
exit();
}
}
header("Location: login.php?errno=1");
exit();
mysql_free_result($res);
mysql_close($conn);
?>
(三)登录管理系统添加新功能
在登录管理系统中添加如下功能:如何在管理界面显示登录成功的用户名,到数据库中去验证用户。
要修改的代码为:
$sql="select password,name from admin where id=$id";
$res=mysql_query($sql,$conn);
if($row=mysql_fetch_assoc($res)){
//查询到,取数据库密码
if($row['password']==md5($password)){
//取出名字.
$name=$row['name'];
header("Location: empManage.php?name=$name");
exit();
}
}
同时在empmanage.php中修改代码:
<?php
echo "欢迎 ".$_GET['name']." 登录成功!";
echo "<br/><a href='login.php'>返回重新登录</a>";
?>
(四)完成管理用户功能,考虑分页情况
分页是任何一个网站(bbs、网上商城、blog)都会使用到的技术,因此学习b/s开发就一定要掌握该技术。
我们先讲讲分页的算法:
我们需要定义四个变量,它们有各自的用处
pageSize : 每页显示多少条记录 pageNow : 希望显示第几页
pageCount : 一共有多少页 rowCount : 共有多少条记录
说明:
pageSize 是指定的
pageNow 是用户选择的
rowCount 是从表中查询得到的
pageCount 是计算出来的 该计算式为
if(rowCount%pageSize==0){
pageCount=rowCount/pageSize;
}else{
pageCount=rowCount/pageSize+1;
}
举例说明:
有用户表 共 9条记录:
rowCount=9;
每页显示3条记录: pageSize=3;
那么根据我们的算法:
pageCount=3 ,刚好不多不少
如果每页显示4条记录
pageSize=4 那么
pageCount=3 , 那么最后一页
只有1条记录
所以,不管怎样都是正确的。
mysql :
select * from 表名 where 条件 limit 从第几条取, 取出几条记录(pageSize)
分页是非常有趣的,我们在employeeList页面增加显示用户信息,并进行分页显示。
同时考虑实现 10页翻页的功能
思路的分析:
$page_whole=10;
$start=floor(($pageNow-1)/$page_whole)*$page_whole+1;
$index=$start;
//整体每10页向前翻
//如果当前pageNow在1-10页数,就没有向前翻动的超连接
if($pageNow>$page_whole){
echo " <a href='empList.php?pageNow=".($start-1)."'> << </a>";
}
//定$start 1---》10 floor((pageNow-1)/10)=0*10+1 11->20 floor((pageNow-1)/10)=1*10+1 21-30 floor((pageNow-1)/10)=2*10+1
for(;$start<$index+$page_whole;$start++){
echo "<a href='empList.php?pageNow=$start'>[$start]</a>";
}
//整体每10页翻动
echo " <a href='empList.php?pageNow=$start'> >> </a>";
目前我们为了完成分页,是写在EmpSerivice 类,我们能不能做一个通用的方法,可以适用于各种情况的分页?如何做一个通用的分页模块(函数)。增加一个新的功能,删除某个雇员。
思路:
设计一个FenyePage类,该类可以封装我们分页需要的各种信息。
class FenyePage{
public $pageSize=6;
public $res_array; //这是显示数据
public $rowCount; //这是从数据库中获取
public $pageNow; //用户指定的
public $pageCount; //这个是计算得到的
}
雇员管理系统的所有源代码:
login.php:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<h1>管理员登录系统</h1>
<form action="loginProcess.php" method="post">
<table>
<tr><td>用户id</td><td><input type="text" name="id"/></td></tr>
<tr><td>密 码</td><td><input type="password" name="password"/></td></tr>
<tr>
<td><input type="submit" value="用户登录"/></td>
<td><input type="reset" value="重现填写"/></td>
</tr>
</table>
</form>
<?php
//接收errno
if(!empty($_GET['errno'])){
//接收错误编号
$errno=$_GET['errno'];
if($errno==1){
echo "<br/><font color='red' size='3'>你的用户名或者密码错误</font>";
}
}
?>
</html>
loginProcess.php:
<?php
//接收用户的数据
//1.id
$id=$_POST['id'];
//2.密码
$password=$_POST['password'];
//得到链接
$conn=mysql_connect("localhost","root","123456");
if(!$conn){
die("数据库链接失败".mysql_error());
}
mysql_query("set names utf8",$conn) or die(mysql_error());
mysql_select_db("empdb",$conn) or die(mysql_error());
//防止SQL注入.
$sql="select password,name from admin where id=$id";
$res=mysql_query($sql,$conn);
if($row=mysql_fetch_assoc($res)){
//查询到,取数据库密码
if($row['password']==md5($password)){
//取出名字.
$name=$row['name'];
header("Location: empManage.php?name=$name");
exit();
}
}
header("Location: login.php?errno=1");
exit();
mysql_free_result($res);
mysql_close($conn);
?>
empManage.php
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<?php
echo "欢迎 ".$_GET['name']." 登录成功!";
echo "<br/><a href='login.php'>返回重新登录</a>";
?>
<h1>主界面</h1>
<a href='empList.php'>管理用户</a><br/>
<a href='#'>添加用户</a><br/>
<a href='#'>查询用户</a><br/>
<a href='#'>退出系统</a><br/>
</html>
empList.php:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>雇员信息列表</title>
<script type="text/javascript">
<!--
function confirmDele(val){
return window.confirm("是否要删除id="+val+"的用户?");
}
//-->
</script>
</head>
<?php
require_once 'EmpService.class.php';
require_once 'FenyePage.class.php';
$empService=new EmpService();
//创建一个FenyePage对象实例
$fenyePage=new FenyePage();
//给fenyePage指定必须的数据
$fenyePage->pageNow=1;
$fenyePage->pageSize=6;
//这里我们需要根据用户的点击来修改$pageNow这个值
//这里我们需要判断 是否有这个pageNow发送,有就使用,
//如果没有,则默认显示第一页
if(!empty($_GET['pageNow'])){
$fenyePage->pageNow=$_GET['pageNow'];
}
//调用getEmpListByPage方法,该方法可以把fenyePage完成
$empService->getFenyePage($fenyePage);
echo "<table border='1px' bordercolor='green' cellspacing='0px' width='700px'>";
echo "<tr><th>id</th><th>name</th><th>grade</th><th>email</th><th>salary</th><th>删除用户</th><th>修改用户</th></tr>";
for($i=0;$i<count($fenyePage->res_array);$i++){
$row=$fenyePage->res_array[$i];
echo "<tr><td>{$row['id']}</td><td>{$row['name']}</td><td>{$row['grade']}</td><td>{$row['email']}</td><td>{$row['salary']}</td>".
"<td><a onclick='return confirmDele({$row['id']})' href='empProcess.php?flag=del&id={$row['id']}'>删除用户</a></td><td><a href='#'>修改用户</a></td></tr>";
}
echo "<h1>雇员信息列表 </h1>";
echo "</table>";
//显示上一页和下一页
echo $fenyePage->navigate;
//可以使用for打印超链接
?>
<form action="empList.php">
跳转到:<input type="text" name="pageNow" />
<input type="submit" value="GO">
</form>
</html>
empProcess.php:
<?php
require_once 'EmpService.class.php';
//接收用户要删除的用户id
//创建了EmpService对象实例
$empService=new EmpService();
//先看看用户要分页还是删除某个雇员
if(!empty($_GET['flag'])){
//这是我们知道要删除用户
$id=$_GET['id'];
//echo "你希望删除的用户id=$id";
if($empService->delEmpById($id)==1){
//成功!
header("Location: ok.php");
exit();
}else{
//失败!
header("Location: error.php");
exit();
}
}
?>
SqlHelper.Class.php:
<?php
require_once 'SqlHelper.class.php';
class EmpService{
//一个函数可以获取共有多少页
function getPageCount($pageSize){
//需要查询$rowCount
$sql="select count(id) from emp";
$sqlHelper=new SqlHelper();
$res=$sqlHelper->execute_dql($sql);
//这样就可以计算$pageCount
if($row=mysql_fetch_row($res)){
$pageCount=ceil($row[0]/$pageSize);
}
//释放资源关闭连接
mysql_free_result($res);
//关闭连接
$sqlHelper->close_connect();
return $pageCount;
}
//一个函数可以获取应当显示的雇员信息
function getEmpListByPage($pageNow,$pageSize){
$sql="select * from emp limit ".($pageNow-1)*$pageSize.",$pageSize";
$sqlHelper=new SqlHelper();
//这里的$res就是一个二维数组
$res=$sqlHelper->execute_dql2($sql);
//释放资源和关闭连接
//关闭连接
$sqlHelper->close_connect();
return $res;
}
//第二种使用封装的方式完成的分页(业务逻辑到这里)
function getFenyePage($fenyePage){
//创建一个SqlHelper对象实例
$sqlHelper=new SqlHelper();
$sql1="select * from emp limit "
.($fenyePage->pageNow-1)*$fenyePage->pageSize.",".$fenyePage->pageSize;
$sql2="select count(id) from emp";
$sqlHelper->exectue_dql_fenye($sql1,$sql2,$fenyePage);
$sqlHelper->close_connect();
}
//根据输入id删除某个用户
function delEmpById($id){
$sql="delete from emp where id=$id";
//创建SqlHelper对象实例
$sqlHelper=new SqlHelper();
//返回0, 1 ,2
return $sqlHelper->execute_dml($sql);
}
}
?>
FenyePage.class.php:
<?php
//这是一个用于保存分页信息的类
class FenyePage{
public $pageSize=6;
public $res_array; //这是显示数据
public $rowCount; //这是从数据库中获取
public $pageNow=1; //用户指定的
public $pageCount; //这个是计算得到的
public $navigate; //分页导航
}
?>
error.php:
<?php
header("content-type:text/html;charset=utf-8");
echo "对不起你操作失败<br/>";
echo "<a href='empManage.php'>返回主界面</a>";
?>
Ok.php:
<?php
header("content-type:text/html;charset=utf-8");
echo "恭喜你操作成功<br/>";
echo "<a href='empManage.php'>返回主界面</a>";
?>
【推荐阅读】陈力:传智播客古代 珍宝币 泡泡龙游戏开发第42讲:PHP数据库开发案例