PHP访问数据库复习
一、数据库知识
1. 数据库设计(三范式)
1NF
:原子性 字段不可再分,否则就不是关系数据库。
如果有一个地址字段,却要常常查询地址中的城市,就要把地址分为省、市、街道等。
2NF
:唯一性 一个表只说明一个事物。
表:学号, 姓名, 年龄, 课程名称, 成绩, 学分。
这个表明显说明了两个事务:学生信息, 课程信息。
存在的问题:
-
数据冗余:每条记录都含有相同信息。
-
删除异常:删除所有学生成绩,就把课程信息全删除了。
-
插入异常:学生未选课,无法记录进数据库。
-
更新异常:调整课程学分,所有行都调整。
修改:
-
学生:Student(学号, 姓名, 年龄)。
-
课程:Course(课程名称, 学分)。
-
选课关系:SelectCourse(学号, 课程名称, 成绩)。
3NF
:每列都与主键有直接关系,不存在传递依赖。
订单:订单号,商品名称,数量,客户编号,客户姓名,联系电话。关键字为订单号。
存在传递依赖:(订单号)->(客户编号)->(客户姓名,联系电话)
存在问题:
- 数据冗余:有重复值。
- 更新异常:有重复的冗余信息,修改时需要同时修改多条记录,否则会出现数据不一致的情况。
- 删除异常。
修改:
-
订单:(订单号,商品名称,数量,客户编号)
-
客户:(客户编号,客户姓名,联系电话)
2. 建库建表
采用phpMyAdmin管理MySQL数据库。
1) MySQL中的数据类型
-
INT:用于存储标准的整数,占4个字节。
-
VARCHAR:是一种可变长度的字符串类型。
-
CHAR:是一种固定长度的字符串类型。
-
TEXT:用于存储比较长的字符串,或二进制数据。
-
BOOL:即布尔型数据。
-
DATETIME:保存日期/时间的数据类型,不能指定长度。
-
auto_increment(自动递增) :可以自动递增或随机产生一个整数,常用来自动产生唯一编号。
2)SQL语言
查询
select 字段列表 from 表名 where 条件
新增数据
insert into 表名(字段列表v) values(值列表)
修改数据
update 表名 set 字段1=值1,字段2=值2 where 条件
删除数据
delete from 表名 where 条件
二、PDO
1. PDO简介
PDO(PHP Data Object)
是PHP 5新加入的一个重大功能,因为在PHP 5以前php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么 php_mysql.dll、php_pgsql.dll、php_mssql.dll、php_sqlite.dll等等扩展来连接MySQL、PostgreSQL、MS SQL Server、SQLite,无比烦琐和低效。
PHP后续版本中也将默认使用PDO
的方式连接,mysql扩展将被作为辅助。
2. PDO配置
PHP.ini中,去掉"extension=php_pdo.dll"
前面的";"号,若要连接数据库,还需要去掉与PDO
相关的数据库扩展前面的";"号,然后重启Apache服务器即可。
extension=php_pdo.dll //PDO驱动程序共享扩展必须有 extension=php_pdo_mysql.dll //mysql驱动 extension=php_pdo_sqlite.dll //sqlite驱动 extension=php_pdo_mssql.dll //SQL Server驱动 extension=php_pdo_odbc.dll //odbc驱动 extension=php_pdo_oci8.dll //oracle驱动
3. PDO连接mysql数据库
<?php $dsn='mysql:host=服务器名称;dbname=数据库名'; $db=new PDO($dsn, 'root', ''); ?>
4. PDO常用方法及其应用
-
query($sql);
//用于执行查询SQL语句。返回PDOStatement对象。 -
exec();
//用于执行增删改操作,返回影响行数。 -
setAttribute();
//设置一个“数据库连接对象”属性。 -
lastInsertId();
返回最后插入行的ID。 -
fetch();
//从结果集中获取下一行。 -
fetchAll();
//返回一个包含结果集中所有行的数组。
5. PDO操作MYSQL数据库实例
1)数据库
-- phpMyAdmin SQL Dump -- version 4.1.14 -- http://www.phpmyadmin.net -- -- Host: 127.0.0.1 -- Generation Time: 2016-06-19 10:49:41 -- 服务器版本: 5.6.17 -- PHP Version: 5.5.12 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -- -- Database: `test` -- -- -------------------------------------------------------- -- -- 表的结构 `userinfo` -- CREATE TABLE IF NOT EXISTS `userinfo` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名', `password` char(32) NOT NULL DEFAULT '' COMMENT '密码', `nickname` varchar(30) NOT NULL DEFAULT '' COMMENT '昵称', `email` varchar(60) NOT NULL DEFAULT '' COMMENT '电子邮箱', `login_count` int(11) NOT NULL DEFAULT '0' COMMENT '登录次数', `login_time` int(11) NOT NULL DEFAULT '0' COMMENT '登录时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ; -- -- 转存表中的数据 `userinfo` -- INSERT INTO `userinfo` (`id`, `username`, `password`, `nickname`, `email`, `login_count`, `login_time`) VALUES (1, 'admin', '123', '管理员', 'admin@163.com', 0, 0), (2, 'test', '', '测试', 'test@163.com', 0, 0), /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
2)检索
<?php header('Content-type:text/html;charset=utf-8'); //1. 连接数据库 try{ $dsn='mysql:host=localhost;dbname=test'; $pdo=new PDO($dsn, 'root', ''); }catch( PDOException $e){ echo "error:". $e->getMessage() . '<br>'; exit(); } //设置字符编码为utf8,防止乱码 // $pdo->exec('set names utf8'); $pdo->query('set names utf8'); //2.执行query(查询)返回一个预定义对象 $sql='select * from userinfo'; $rs=$pdo->query($sql); //3.解析数据 //方法1:把所有数据返回到一个数组中 $list=$rs->fetchAll(PDO::FETCH_ASSOC); foreach ($list as $key => $value) { echo '用户名:'.$value['username'].',昵称:'.$value['nickname'].'<br>'; } //方法 2: foreach ($pdo->query($sql) as $value) { echo '用户名:'.$value['username'].',昵称:'.$value['nickname'].'<br>'; } //4. 释放资源 $rs=null; $pdo=null; ?>
3)增加
<?php $dsn="mysql:host=localhost;dbname=db_demo"; $pdo = new PDO($dsn,"root",""); $username='echo'; $nickname='胡悦'; $email='echo@163.com'; $sql="insert into userinfo(username,nickname,email) values('{$username}','{$nickname}','{$email}')"; if($pdo -> exec()){ echo "插入成功!"; echo $pdo -> lastinsertid(); } ?>
4)修改
<?php $dsn="mysql:host=localhost;dbname=db_demo"; $pdo = new PDO($dsn,"root",""); $email='echo@163.com'; $sql="update userinfo set email='{$email}' where id=4"; $pdo -> exec($sql); echo '修改成功'; ?>
5) 删除
<?php $dsn="mysql:host=localhost;dbname=db_demo"; $pdo = new PDO($dsn,"root",""); $sql="delete from userinfo where id=4"; if($pdo -> exec()){ echo "删除成功!"; } ?>
6. 综合实例
数据库链接文件(cn.php)
<?php //建立数据库连接 try{ $dsn='mysql:host=localhost;dbname=test'; $pdo=new PDO($dsn, 'root', ''); //设置字符集为utf8 $pdo->query('set names utf8'); //设置PDO错误警告模式,用于调试 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); }catch( PDOException $e){ echo "error:". $e->getMessage() . '<br>'; exit(); } ?>
登录检测文件(check_login.php)
<?php session_start(); if (!isset($_SESSION['username'])) { header('Location:login.html'); } ?>
登录页面(login.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h3>登录</h3> <form action="check.php" method="post"> <p> <input type="text" name="username" placeholder="用户名"> </p> <p> <input type="text" name="password" placeholder="密码"> </p> <p> <button type="submit">登录</button> <a href="reg.html">注册</a> </p> </form> </body> </html>
登录检测页面(check.php)
<?php header('Content-type:text/html;charset=utf8'); $username=trim($_POST['username']); $username=strtolower($username); $password=$_POST['password']; $password=addslashes($password); //包含数据库连接文件,建立数据库连接 require('cn.php'); $sql="select * from userinfo where username='{$username}' and password='{$password}'"; // $sql="select * from userinfo"; $rs=$pdo->query($sql); $result=$rs->fetch(PDO::FETCH_ASSOC); if ($result) { //echo '登录成功!欢迎你,'.$result['nickname']; session_start(); $_SESSION['username']=$username; $_SESSION['nickname']=$result['nickname']; header('Location:list.php'); }else{ echo '<script>alert("用户名或密码错误");history.back()</script>'; exit(); } ?>
用户信息列表页(list.php)
<?php //防跳墙,需要在登录后的每个页面上包含 require('check_login.php'); echo "<p>{$_SESSION['nickname']},你好!<a href='logout.php'>注销</a></p>" ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户列表</title> <style> table{ width:60%; border-collapse: collapse; } table,th,td{ border:1px solid #aaa; } </style> </head> <body> <?php require('cn.php'); $sql="select * from userinfo"; ?> <table> <caption>用户列表</caption> <thead> <tr> <th>用户名</th> <th>昵称</th> <th>email</th> <th>登录次数</th> <th>登录时间</th> <th>操作</th> </tr> </thead> <tbody> <?php foreach ($pdo->query($sql) as $value) {?> <tr> <td><?=$value['username']?></td> <td><?=$value['nickname']?></td> <td><?=$value['email']?></td> <td><?=$value['login_count']?></td> <td><?=empty($value['login_time'])?'':date('Y-m-d',$value['login_time'])?></td> <td><a href="edit.php?id=<?=$value['id']?>">修改</a> <a href="del.php?id=<?=$value['id']?>" onclick="return del_comfirm();">删除</a></td> </tr> <?php } ?> </tbody> </table> <script> function del_comfirm(){ if (confirm('是否确认删除?')) { return true; }else{ return false; } } </script> </body> </html>
删除记录(del.php)
<?php $id=$_GET['id']; require('cn.php'); $sql="delete from userinfo where id={$id}"; if ($pdo->exec($sql)) { $url='list.php'; header('Location:'.$url); } ?>
修改用户信息页面(edit.php)
<?php require('check_login.php'); echo "<p>{$_SESSION['nickname']},你好!<a href='logout.php'>注销</a></p>" ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户信息修改</title> </head> <body> <h3>用户信息修改</h3> <?php $id=$_GET['id']; require('cn.php'); $sql="select * from userinfo where id={$id}"; $rs=$pdo->query($sql); $result=$rs->fetch(PDO::FETCH_ASSOC); if (!$result) { echo '<script>alert("没找到用户");history.back();</script>'; exit(); } ?> <form action="update.php" method="post"> <p> <input type="text" name="username" placeholder="用户名" value="<?=$result['username']?>"> </p> <p> <input type="text" name="nickname" placeholder="昵称" value="<?=$result['nickname']?>"> </p> <p> <input type="email" name="email" placeholder="电子邮箱" value="<?=$result['email']?>"> </p> <p> <input type="hidden" name="id" value="<?=$result['id']?>"> <button type="submit">修改</button> </p> </form> </body> </html>
修改用户信息处理(update.php)
<?php require('check_login.php'); header('Content-type:text/html;charset=utf-8'); $username=trim($_POST['username']); $username=strtolower($username); $id=$_POST['id']; $nickname=$_POST['nickname']; $email=$_POST['email']; require('cn.php'); $sql="select * from userinfo where username='{$username}' and id!={$id}"; $rs=$pdo->query($sql); $result=$rs->fetch(PDO::FETCH_ASSOC); if ($result) { echo '<script>alert("用户名已存在");history.back();</script>'; exit(); } $sql="update userinfo set username='{$username}',nickname='{$nickname}',email='{$email}' where id={$id}"; $pdo->exec($sql); header('Location:list.php'); ?>
用户注册页面(reg.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <h3>注册</h3> <form action="reg.php" method="post"> <p> <input type="text" name="username" placeholder="用户名"> </p> <p> <input type="password" name="password" placeholder="密码"> </p> <p> <input type="text" name="nickname" placeholder="昵称"> </p> <p> <input type="email" name="email" placeholder="电子邮箱"> </p> <p> <button type="submit">注册</button> </p> </form> </body> </html>
用户注册处理(reg.php)
<?php header('Content-type:text/html;charset=utf-8'); $username=trim($_POST['username']); $username=strtolower($username); $password=$_POST['password']; $nickname=$_POST['nickname']; $email=$_POST['email']; require('cn.php'); $sql="select * from userinfo where username='{$username}'"; $rs=$pdo->query($sql); $result=$rs->fetch(PDO::FETCH_ASSOC); if ($result) { echo '<script>alert("用户名已存在");history.back();</script>'; exit(); } $sql="insert into userinfo(username,nickname,password,email) values('{$username}','{$nickname}','{$password}','{$email}')"; // echo $sql; if ($pdo->exec($sql)) { echo '注册成功!'; echo '欢迎你,'.$nickname; echo ',<a href="login.html">单击登录</a>' }else{ echo '<script>alert("注册失败");history.back();</script>'; exit(); } ?>