当考虑连接到MySQL数据库服务器的时候,有三种主要的API可供选择:
PHP的MySQL扩展 PHP的mysqli扩展 PHP数据对象(PDO)下面介绍3种扩展的区别:
a.什么是PHP的MySQL扩展?
这是设计开发允许PHP应用与MySQL数据库交互的早期扩展。mysql扩展提供了一个面向过程 的接口,并且是针对MySQL4.1.3或更早版本设计的。因此,这个扩展虽然可以与MySQL4.1.3或更新的数据库服务端 进行交互,但并不支持后期MySQL服务端提供的一些特性。
Note: 如果你是使用MySQL4.1.3或更新的服务端版本,强烈建议你使用mysqli 扩展替代它。
mysql扩展的源代码在PHP扩展目录ext/mysql下。b.什么是PHP的mysqli扩展?
mysqli扩展,我们有时称之为MySQL增强扩展,可以用于使用 MySQL4.1.3或更新版本中新的高级特性。mysqli扩展在PHP 5及以后版本中包含。
mysqli扩展有一系列的优势,相对于mysql扩展的提升主要有:
面向对象接口 prepared语句支持(预编译) 多语句执行支持 事务支持 增强的调试能力 嵌入式服务支持Note:
如果你使用MySQL4.1.3或更新版本,强烈建议你使用这个扩展。
在提供了面向对象接口的同时也提供了一个面向过程的接口。
mysqli扩展是使用PHP扩展框架构建的,它的源代码在PHP源码目录下的ext/mysqli中
c.什么是PDO?
PHP数据对象,是PHP应用中的一个数据库抽象层规范。PDO提供了一个统一的API接口可以使得你的PHP应用不去关心具体要 连接的数据库服务器系统类型。也就是说,如果你使用PDO的API,可以在任何需要的时候无缝切换数据库服务器,比如从Firebird 到MySQL,仅仅需要修改很少的PHP代码。
其他数据库抽象层的例子包括Java应用中的JDBC以及Perl中的DBI。
当然,PDO也有它自己的先进性,比如一个干净的,简单的,可移植的API,它最主要的缺点是会限制让你不能使用 后期MySQL服务端提供所有的数据库高级特性。比如,PDO不允许使用MySQL支持的多语句执行。
PDO是基于PHP扩展框架实现的,它的源码在PHP源码目录的ext/pdo下。
什么是PHP的MySQLi扩展
-PHP的MySQLi扩展又称为MySQL增强扩展,mysqli扩展在PHP5 及以后版本中包含。
2. MySQLi扩展相对于MySQL扩展的优势
-基于面向过程和面向对象的使用
-支持预处理语句
-支持事务
-配置PHP配置文件(php.ini),开启php_mysqli.dll扩展
去掉前面分号
-配置extension_dir=’ext目录所在位置’
-重新启动服务器
如何验证我们的mysqli扩展是否可以使用呢?4种方法<?php//验证mysqli扩展是否已开启phpinfo();//检测扩展是否已加载返回的结果是true 或false。var_dump(extension_loaded('mysqli'));var_dump(extension_loaded('gettext'));
介绍MySQLi面向对象中的常用方法和属性,实现对数据库的增删改查,以及预处理语句、事务的使用
Mysqli连接数据库案例:连接school数据库
//mysqli连接mysql数据库//第一种方法 1.建立到MySQL数据的连接$mysqli=new mysqli('localhost','root','root');$sql='select id,`name`,age from tb_student;';print_r($mysqli);//2.打开指定的数据库,我这里用的school数据库$mysqli->select_db('school');//第二种方法:打开连接的同时,并且打开数据库$mysqli =@new mysqli('localhost','root','root','school');//$mysqli->connect_errno :得到连接产生的错误编号;连接数据库,一旦出错会产生相应的错误号//$mysqli->connect_error:得到连接产生的错误信息if($mysqli->connect_errno){
//die() 函数输出一条消息,并对出当前脚本。该函数是exit()函数的别名 die('连接错误:'.$mysqli->connect_error);}else{ echo '连接成功';}echo '<pre>';print_r($mysqli);echo '</pre>';
打开连接属性 print_r($mysqli); 显示一些信息
连接数据库的整个步骤:连接school数据库,并向数据库添加一张表(教师信息表)
//1.打开连接的同时,并且打开数据库$mysqli =@new mysqli('localhost','root','root','school');//$mysqli->connect_errno :得到连接产生的错误编号;连接数据库,一旦出错会产生相应的错误号//$mysqli->connect_error:得到连接产生的错误信息if($mysqli->connect_errno){ die('连接错误:'.$mysqli->connect_error);}//2.设置默认的客户端编码方式为 utf8$mysqli->set_charset('utf8');//3.执行sql查询//PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,//如果用传统的输出方法 ——按字符串输出的话,//肯定要有大量的转义符来对字符串中的引号等特殊字符进行转义,以免出现语法错误。//如果是一两处还可以容忍,但是要是一个完整的 html文本或者是一个200行的js我想是谁都会崩溃的。//这就是PHP为什么要引入一个定界符的原因——至少一大部分原因是这样的。/* 1.PHP定界符的作用就是按照原样,包括换行格式什么的,输出在其内部的东西;2.在PHP定界符中的任何特殊字符都不需要转义;3.PHP定界符中的PHP变量会被正常的用其值来替换。 PHP中的定界符格式是这样的:<<<Eof……Eof;*/$sql=<<<EOF create table if not exists t_teacher( id int UNSIGNED auto_increment primary key, teaname varchar(20) not null UNIQUE, pwd char(32) not null, email varchar(30) not null);EOF;$res=$mysqli->query($sql);var_dump($res);//4.关闭连接$mysqli->close();
可通过navicat查看数据表是否创建成功
向用户信息表t_user表添加数据,表结构如下:
连接数据库(防止乱码,在头部设置编码utf8)
//设置字符集,防止乱码header('content-type:text/html;charset=utf-8');//1.连接数据库$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}
向数据库表添加数据(插入一条或多条记录)//向数据表中插入数据(一条或多条)$sql="insert into t_user(id,`name`,`password`,sex) VALUES(DEFAULT ,'彭姐3','123456','女'); ";//$sql="select * from t_user";//query() 执行单条sql语句;只能执行一条sql语句//可以一次向数据表添加多条记录//$sql="insert into t_user(id,`name`,`password`,sex) VALUES(DEFAULT ,'彭姐4','123454','男'),(DEFAULT ,'彭姐5','123456','女'); ";$res=$mysqli->query($sql);//如果插入成功,则返回id或者成功的条数;如果失败则返回失败的原因if($res){ //insert_id 得到上一插入操作产生的auto_increment(自增长)的值。 echo "恭喜您是网站第".$mysqli->insert_id.'位用户<br/>'; //affected_rows 得到上一步操作产生的受影响记录条数 //affected_rows 值会有3种情况:①受影响的条数 ② -1 sql语句写的有问题 3.0代表没有受影响的行数 echo "有".$mysqli->affected_rows.'条记录被影响';}else{ //得到上一步操作产生的错误号和错误信息 echo '添加失败的错误号及错误信息'.$mysqli->errno.':'.$mysqli->error;}
注意:query只能执行一条sql语句
//修改记录 (更新用户信息表第4条记录姓名及性别)$sql=" UPDATE t_user set `name`='彭杰',`sex`='男' WHERE id=4;";$res=$mysqli->query($sql);if($res){ // affected_rows 值会有3种情况:①受影响的条数 ② -1 sql语句写的有问题 3.0代表没有受影响的行数 echo $mysqli->affected_rows."条记录被删除";}else{ echo '失败错误号及原因'.$mysqli->error.':'.$mysqli->errno;}
//mysqli实现删除记录操作$sql=" DELETE FROM t_user WHERE id<5;";$res=$mysqli->query($sql);if($res){ echo $mysqli->affected_rows."条记录被删除";}else{ echo '失败'.$mysqli->error;}//关闭mysql的连接$mysqli->close();
注意:1.执行完操作记得关闭连接
2. affected_rows 值会有3种情况:①受影响的条数 ② -1 sql语句写的有问题 3.0代表没有受影响的行数
$sql="select id,`name`,age from tb_student";//将查询结果放到$result中$result=$mysqli->query($sql);print_r($result);
如果成功,返回结果集信息,如果失败返回 bool(false).
如果结果集查到,并且有数据,返回记录条数 num_rows
$sql="select id,`name`,age from tb_student";//将查询结果放到$result中$result=$mysqli->query($sql);if ($result && $result->num_rows>0){ echo '查到记录条数:'.$result->num_rows;}else{ echo '查询错误或结果集中没有记录';}
取出结果集种的记录条
$sql="select id,`name`,age from tb_student";//将查询结果放到$result中$result=$mysqli->query($sql);if ($result && $result->num_rows>0){ $rows=$result->fetch_all(MYSQLI_BOTH); //获取结果集中所有记录,默认返回的是二维的索引+关联的形式 //$rows=$result->fetch_all(MYSQLI_NUM) //索引数组 //$rows=$result->fetch_all(MYSQLI_ASSOC) //关联数组 $row=$result->fetch_row(); //获得结果集中一条记录作为索引数组返回 $row1=$result->fetch_assoc(); //获得结果集中一条记录作为关联数组返回 echo '<pre>'; print_r($rows); echo '<hr/>'; print_r($row); echo '<hr/>'; print_r($row1);
echo '</pre>';
//释放结果集 3种方法 ://$result->free(); $result->close; $result->free_result; 都是释放与一个结果集相关的内容$result->free();}else{ echo '查询错误或结果集中没有记录';}
h5 创建一个表格 user.php
查询数据表中的记录 user.php
<?php $mysqli=new mysqli('localhost','root','root','school'); if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error); } $mysqli->set_charset('utf8'); $sql="select id,`name`,age from tb_student"; $mysqli_result=$mysqli->query($sql); if ($mysqli_result && $mysqli_result->num_rows>0){ while($row=$mysqli_result->fetch_assoc()){ $rows[]=$row; } } //print_r($rows);?>
将数据绑定到数据表中 user.php<body><h2>用户列表-<a href="addUser.php">添加用户</a></h2> <table border="1" cellpadding="0" cellspacing="0" width="80%" bgcolor="#ABCDEF"> <tr> <td>编号</td> <td>用户名</td> <td>年龄</td> <td>操作</td> </tr> <?php $i=1; foreach ($rows as $row):?> <tr> <td><?php echo $row['id'];?></td> <td><?php echo $row['name'];?></td> <td><?php echo $row['age'];?></td> <td><a href="editUser.php">更新</a>|<a href="doAction.php">删除</a></td> </tr> <?php endforeach;?> </table></body>
1.addUser.php
<body><h2>添加用户</h2><form action="doAction.php?act=addUser" method="post"> <table border="1" cellspacing="0" cellpadding="0" bgcolor="#abcdef" width="80%"> <tr> <td>用户名</td> <td><input type="text" name="username" id="" placeholder="请输入合法用户名" required="required"></td> </tr> <tr> <td>年龄</td> <td><input type="number" name="age" min='1' max="125" id="" placeholder="请输入合法年龄" required="required"></td> </tr> <tr> <td colspan="2"><input type="submit" value="添加用户"></td> </tr> </table></form></body>
Required:必填项
2.接收页面 doAction.php
<?phpheader('content-type:text/html;charset=utf-8');$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$Name=$_POST['username'];//将用户名进行转义$username=$mysqli->escape_string($Name);$age=$_POST['age'];$act=$_GET['act'];//根据不同操作完成不同功能switch($act){ case 'addUser': //echo '添加用户操作'; $sql="INSERT tb_student(`name`,age) values('{$Name}','{$age}')"; $res=$mysqli->query($sql); if($res){ $insert_id=$mysqli->insert_id; echo "<script type='text/javascript'> alert('添加成功,网站的第{$insert_id}位用户'); location.href='user.php'; </script>"; }else{ echo "<script type='text/javascript'> alert('添加失败,重新添加'); location.href='addUser.php'; </script>"; } break;}
<td><a href="editUser.php">更新</a>|<a href="doAction.php?act=delUser&id=<?php echo $row['id'];?>">删除</a></td>
doAction.php页面 添加删除操作相应内容<?phpheader('content-type:text/html;charset=utf-8');$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$act=$_GET['act'];//根据不同操作完成不同功能switch($act){ case 'addUser': $Name=$_POST['username']; //将用户名进行转义 $username=$mysqli->escape_string($Name); $age=$_POST['age']; //echo '添加用户操作'; $sql="INSERT tb_student(`name`,age) values('{$Name}','{$age}')"; $res=$mysqli->query($sql); if($res){ $insert_id=$mysqli->insert_id; echo "<script type='text/javascript'> alert('添加成功,网站的第{$insert_id}位用户'); location.href='user.php'; </script>"; exit; }else{ echo "<script type='text/javascript'> alert('添加失败,重新添加'); location.href='addUser.php'; </script>"; exit; } break; case 'delUser': $id=$_GET['id']; //echo '删除记录'.$id; $sql="delete from tb_student where id=".$id; $res=$mysqli->query($sql); if($res){ $mes='删除成功'; }else{ $mes='删除失败'; } $url='user.php'; echo "<script type='text/javascript'> alert('{$mes}'); location.href='{$url}'; </script>"; exit; break;}
<?php$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$mysqli->set_charset('utf8');$id=$_GET['id'];//echo $id;$sql="select id,`name`,age from tb_student where id=".$id;$mysqli_result=$mysqli->query($sql);if ($mysqli_result && $mysqli_result->num_rows>0){ $row=$mysqli_result->fetch_assoc();}//print_r($row);?><!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body><h2>编辑用户</h2><form action="doAction.php?act=editUser&id=<?php echo $id;?>" method="post"> <table border="1" cellspacing="0" cellpadding="0" bgcolor="#abcdef" width="80%"> <tr> <td>用户名</td> <td><input type="text" name="username" id="" value="<?php echo $row['name'];?>" required="required"></td> </tr> <tr> <td>年龄</td> <td><input type="number" name="age" min='1' max="125" id="" value="<?php echo $row['age'];?>" required="required"></td> </tr> <tr> <td colspan="2"><input type="submit" value="编辑用户"></td> </tr> </table></form></body></html>
介绍MySQLi面向对象中的常用方法和属性,实现对数据库的增删改查,以及预处理语句、事务的使用。
1.查增删的多条语句实现
header('content-type:text/html;charset=utf-8');//查询数据表中的数据$mysqli=@new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('错误信息是:'.$mysqli->connect_error);}//设置字符集$mysqli->set_charset('utf8');$sql='select id,`name`,age from tb_student;';$sql.="insert into tb_student(`name`,age) VALUES ('王芳',54);";$sql.="delete from tb_student where id=2;";//multi_query($sql):针对多条SQL语句的查询//只要第一条sql执行成功即返回true;//一般执行多条语句的时候,更多的是执行查询$res=$mysqli->multi_query($sql);var_dump($res);
2.实现多条查询语句
//use_result() /store_result():获取第一条查询产生的结果集//more_results():检测是否有更多的结果集//next_result():将结果集指针向下移动一位if($mysqli->multi_query($sql)){ do{ if($mysqli_result=$mysqli->store_result()){ $rows[]=$mysqli_result->fetch_all(MYSQLI_ASSOC); } }while($mysqli->more_results()&&$mysqli->next_result());}else{ echo $mysqli->error;}echo '<pre>';print_r($rows);//关闭连接$mysqli->close();
3-1 MySQLi针对多条SQL语句的执行 (14:12)1.查增删的多条语句实现
header('content-type:text/html;charset=utf-8');//查询数据表中的数据$mysqli=@new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('错误信息是:'.$mysqli->connect_error);}//设置字符集$mysqli->set_charset('utf8');$sql='select id,`name`,age from tb_student;';$sql.="insert into tb_student(`name`,age) VALUES ('王芳',54);";$sql.="delete from tb_student where id=2;";//multi_query($sql):针对多条SQL语句的查询//只要第一条sql执行成功即返回true;//一般执行多条语句的时候,更多的是执行查询$res=$mysqli->multi_query($sql);var_dump($res);
2.实现多条查询语句
//use_result() /store_result():获取第一条查询产生的结果集//more_results():检测是否有更多的结果集//next_result():将结果集指针向下移动一位if($mysqli->multi_query($sql)){ do{ if($mysqli_result=$mysqli->store_result()){ $rows[]=$mysqli_result->fetch_all(MYSQLI_ASSOC); } }while($mysqli->more_results()&&$mysqli->next_result());}else{ echo $mysqli->error;}echo '<pre>';print_r($rows);//关闭连接$mysqli->close();
<?phpheader('content-type:text/html;charset=utf-8');//连接数据库$mysqli=@new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('错误信息是:'.$mysqli->connect_error);}//设置字符集$mysqli->set_charset('utf8');$sql="insert into tb_student(`name`,age) VALUES (?,?);";//准备预处理语句$mysqli_stmt=$mysqli->prepare($sql);//预防sql语句出错:Fatal error: Call to a member function bind_param() on boolean in D:\phpStudy\PHPTutorial\WWW\UserManager\multi\prepare.php on line 18//判断sql语句是否有问题if(!$mysqli_stmt){ die($mysqli->error);}//需要指定参数类型 s:字符串 i:整型 d:浮点型$user='king';$age=10;//绑定参数$mysqli_stmt->bind_param('si',$user,$age);//$mysqli_stmt->bind-param('si',$user,$age);//执行预处理语句if($mysqli_stmt->execute()){ echo $mysqli_stmt->insert_id; echo '<br/>';}else{ $mysqli_stmt->error;}
1.会产生sql注入的情况
<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body><h2>登陆页面</h2><form action="doLogin.php" method="post"> username: <input type="text" name="username" id=""><br/> password: <input type="password" name="password" id=""><br/> <input type="submit" value="登陆"></form></body></html>
<?php$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$mysqli->set_charset('utf8');$username=$_POST['username'];$password=$_POST['password'];//不对数据做处理的sql语句$sql="select * from t_user where `name`='{$username}' AND `password`='{$password}';";$mysqli_result=$mysqli->query($sql);//$mysqli_result->num_rows; 执行的条数,查询成功为1//echo $mysqli_result->num_rows;exit;//输入 $mysqli_result->num_rows‘ or 1=1# sql注入if($mysqli_result && $mysqli_result->num_rows>0){ echo '登陆成功';}else{ echo '登陆失败';}
<?phpheader('content-type:text/html;charset=utf-8');$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$mysqli->set_charset('utf8');//sql查询语句$sql="select id,`name`,age from tb_student where id>=?";//准备预处理语句$mysqli_stmt=$mysqli->prepare($sql);$id=5;//绑定参数$mysqli_stmt->bind_param('i',$id);//执行预处理语句if($mysqli_stmt->execute()){ //bind_result()将结果集中的值绑定到我们的变量上 $mysqli_stmt->bind_result($id,$name,$age); //fetch()遍历结果集 while ($mysqli_stmt->fetch()){ echo '编号:'.$id."<br/>"; echo '用户名:'.$name.'<br/>'; echo '年龄:'.$age.'<br/>'; echo '<hr/>'; }}//释放结果集$mysqli_stmt->free_result();//关闭预处理语句$mysqli_stmt->close();//关闭连接$mysqli->close();
用户转账为例的事务实现
1.建表account,准备数据
2.代码实现
<?phpheader('content-type:text/html;charset=utf-8');$mysqli=new mysqli('localhost','root','root','school');if($mysqli->connect_errno){ die('CONNECT ERROR:'.$mysqli->connect_error);}$mysqli->set_charset('utf8');//默认MySQL语句是自动提交的,做事务实现,应先关闭自动提交功能//先关闭mysql自动提交功能 false 关闭; 1 或true 开启自动提交$mysqli->autocommit(false);$sql="update account set money=money-200 WHERE username='king'";$res=$mysqli->query($sql);$res_affect=$mysqli->affected_rows;$sql1="update account set money=money+200 WHERE username='queen'";$res1=$mysqli->query($sql1);$res_affect1=$mysqli->affected_rows;if($res && $res_affect>0 && $res1 && $res_affect1>0){ //提交 $mysqli->commit(); echo '转账成功啦!'; $mysqli->autocommit(true);}else{ $mysqli->rollback(); echo '转账失败';}//关闭连接$mysqli->close();