陈力:传智播客古代 珍宝币 泡泡龙游戏开发第39讲:PHP数据库编程MySQLi扩展库

mysqli扩展允许我们访问MySQL 数据库,并对MySql数据库进行curd操作。mysqli扩展可以进行数据查询、批量执行sql语句、事务回滚、预处理 MySQLi_STMT等操作。请贵阳网站建设的朋友继续往下读。

一、mysql数据库
    mysqli (mysql improve mysql扩展库的增强版)。mysqli扩展允许我们访问MySQL 数据库,并对MySql数据库进行curd操作。可以使用php 的mysqli扩展库去操作mysql数据库。
    mysql扩展库和mysqli扩展库的比较:这两个都是php设计者给我们提供的扩展库。都可以完成对mysql数据库的操作。mysqli扩展库是mysql扩展库的改进版本。mysqli 的稳定性和安全性,效率有所提高。mysqi支持面向对象编程,同时mysqli扩展库考虑到php老程序员,提供面向过程的编程风格(mysqli有两套编程风格)。
    通过mysqli建立连接($conn):
(1)$mysqli=new MySQLi(“主机名”,“用户名”,“密码”,“数据库"); 
if (mysqli_connect_error()) {
    die('Connect Error (' . mysqli_connect_errno() . ') '  . mysqli_connect_error());

(2)$mysqli = mysqli_init();
if (!$mysqli) {
  die('mysqli_init failed');}
if (!$mysqli->real_connect('localhost', 'root', 'root', 'test')) {
  die('Connect Error ('. mysqli_connect_errno() . ') '. mysqli_connect_error());}

mysqli 编程入门实例:
    编写一个程序,这个程序从user1表中读取数据,并打印在网页中。(使用mysqli完成)。
    步骤1:先使用mysqli面向对象的风格,完成案例。
    步骤2:配置php.ini 文件让php支持mysqli扩展库。
           extension=php_mysqli.dll
    步骤3:进行数据库创建,新建表结构。
    步骤4:编写代码。
 <?php
 header("Content-type: text/html;charset=utf-8");
 //mysqli操作mysql数据库(面向对象风格)
 //1.创建MySQLi 对象
 $mysqli=new MySQLi("localhost","root","root","test");
 //验证是否成功
 if($mysqli->connect_error){
  die("连接失败".$mysqli->connect_error);
 }
 $sql="select * from user1";//2. 操作数据库(发送sql)
 $res=$mysqli->query($sql); //$res 是结果集,类型为mysqli result
 //var_dump($res);
 //3. 处理结果 mysql_fetch_row();
 while($row=$res->fetch_row()){
  
  foreach($row as $key=>$val){
   echo "--$val";
  }
  echo "<br/>";
 }
 $res->free();//4. 关闭资源//释放内存
 $mysqli->close();//关闭连接
?>

使用面向过程的方式实现代码:
<?php
 header("Content-type: text/html;charset=utf-8");
 $mysqli=mysqli_connect("localhost","root","root","test");//1.得到mysqli连接
 if(!$mysqli){
  die("连接失败".mysqli_connnect_error($mysqli));
 }
 //2.向数据库发送sql语句(ddl,dml dql ...) 
 $sql="select * from user1";
 $res=mysqli_query($mysqli,$sql);
 //var_dump($res);
 //3.处理得到的结果
 //循环取出$res中的数据mysqli_fetch_row mysql_fetch_row
 while($row=mysqli_fetch_row($res)){
  foreach($row as $key=>$val){
   echo "--$val";
  }
  echo "<br/>";
 }
 mysqli_free_result($res); //4.关闭资源
 mysqli_close($mysqli);
?>

程序中的$res用于代表Sql语句的执行结果。
(1) 如果执行的是dml语句,则返回bool 。
(2) 如果执行的是dql语句,则返回查询结果MySQLi_Result 结果集对象。
(3) 如何从mysql result 取出查询的结果,在mysqli 扩展中,也提供了四种方式来获取mysqli result结果集:
mysqli_result::fetch_assoc <==>    mysql_fetch_assoc
mysqli_result::fetch_row  <==>    mysql_fetch_row
mysqli_result::fetch_array <===> mysql_fetch_array
mysqli_result::fetch_object<===> mysql_fetch_object
    通过var_dump($res) 我们可以更加清楚的知道,当执行查询的时候,mysql_query() 返回 mysql result 类型,执行dml语句返回bool类型。
取出数据结果集有四种方式(mysql_fetch_row,,mysql_fetch_assoc, mysql_fetch_array, ,mysql_fetch_object) 区别?如何选择使用问题?
区别:前两个效率相当:mysql_fetch_row从结果集中取得一行作为索引数组 mysql_fetch_assoc 取出关联数组(需要通过列名来取数据)。
第三个效率偏低:因为mysql_fetch_array从结果集中取得一行作为关联数组和数字数组二者兼有,因此代价高,不推荐使用可用通过print_r或者var_dump来测试。
第四个一般我们不用:因为我们往往自定义对象来处理: mysql_fetch_object 从结果集中取得一行作为对象。
    取出结果集中的数据除了该ppt列举出的案例外:还可以使用如下方法:
while(list($id,$name,$passwd)=mysql_fetch_row($result)){  //这里不能使用mysql_fetch_assoc().必须包含索引数组才可以
 echo $id.$name,$passwd;
}
while($row=mysql_fetch_row($result)){  //这里能使用mysql_fetch_assoc(),或者mysql_fetch_array()
 foreach($row as $val){
  echo $val.”-”;
 }
}
    数据库的连接是非常稀有的资源,用完后要及时释放,如果不能及时、正确的关闭,极易导致系统宕机。使用原则是尽量晚创建,尽量早的释放。 
在mysqli释放结果集有三种方式:
void mysqli_result::free ( void )
void mysqli_result::close ( void )
void mysqli_result::free_result ( void )

面向对象风格:
bool mysqli::close ( void )
过程化风格:
bool mysqli_close ( mysqli $link )

mysql的sql 语句的特别说明:如果操作的字段类型是string型,则要求我们的要用‘’包括。如果操作的字段类型是 数值型,则可以用’80’包括,也可以不用。

二、对mysql数据库进行CRUD
     mysqli::query用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个函数向数据库发送增删改查语句即可。
对users表的增删改操作:
 $mysqli=new MySQLi("localhost","root","root","test");
 if (mysqli_connect_errno()) {
  die("Connect failed: ". mysqli_connect_error());
 } 
 echo $mysqli->server_info."<br/>";
 //如果是查询数据库
 //$sql="select *from user1";
 $sql="delete from user1 where id=90";
 //$sql可以是 insert 和 update
 $mysqli->query(“set names gbk”); //这个设置很重要
 $res=$mysqli->query($sql);
 //证明返回类型是什么
 var_dump($res);
 //判断需要技巧
 if(!$res){
  echo '失败.'.$mysqli->error;
  exit();
 }
 //看看受影响的行数
 if($mysqli->affected_rows>0){
  echo '执行成功!';
 }else{
  echo '记录没有改变';
 }
 $mysqli->close();

三、mysqli扩展库增强--批量执行sql语句
    有时我们需要一次性执行多条sql语句,比如批量增加用户,这时如果单条单条的向mysql数据库发送sql指令,效率不高,这时可以考虑使用批量执行sql语句的方式。
基本使用:
$sqls=“sql语句1;sql语句2;sql语句n”;
$res=mysqli::multi_query($sqls)
说明:如果$sqls是dml语句,则$res返回bool,
如果$sqls是dql语句,则$res返回多个结果集,需要使用 mysqli::store_result 
和 mysqli::next_result配合取出各个结果集。

案例:
请使用mysqli的mysqi::multi_query() 一次性添加三个用户 宋江 卢俊义 吴用。

代码:
<?php
 //1.得到mysqli对象
 $mysqli=new MySQLi("localhost","root","hsp123","test");
 if($mysqli->connect_error){
  die($mysqli->connect_error);
 }
 $sqls="insert into user1 (name,password,email,age) values('宋江','aaa','aa@shu.com',45);";
 $sqls.="insert into user1 (name,password,email,age) values('卢俊义','aaa','aa@shu.com',45);";
 $sqls.="insert into user1 (name,password,email,age) values('吴用','aaa','aa@shu.com',45);";
 //$sqls.="update ;";
 //$sqls.="delete ;";
 $b=$mysqli->multi_query($sqls);
 if(!$b){
  echo "执行失败".$mysqli->error;
 }else{
  echo "ok";
 }
 $mysqli->close();//关闭资源
?>
    批量执行dml语句可以混合使用 delete insert update,但是最好不要使用select。
    批量执行 dql语句:它的作用是可以一次性的取回多个结果集。
案例:
    请使用mysqli的mysqi::multi_query()一次性查询并显示①users表的结构、② users表中用户id ,和用户名字。
<?php
 $mysqli=new MySQLi("localhost","root","hsp123","test");//1.得打mysqli对象
 $sqls="select * from emp;"; //2.批量查询
 $sqls.="select * from user1;";
 $sqls.="desc user1";
 3.处理结果,如果成功,则至少有一个结果集
 if($res=$mysqli->multi_query($sqls)){
  do{
   $result=$mysqli->store_result();//从mysqli连接取出第一个结果集
   //显示mysqli result对象
   while($row=$result->fetch_row()){
    foreach($row as $key => $val){
     echo "--$val";
    }
    echo "<br/>";
   }
   //及时释放$result;
   $result->free();
   if(!$mysqli->more_results()){
    break;
   }
   echo "<br/>******新的结果集*******<br/>";
  }while($mysqli->next_result());
 }
 $mysqli->close();//4.关闭资源
?>

四、mysql的事务处理
     事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。如:网上转账就是典型的要用事务来处理,用以保证数据的一致性。
     为什么需要事务控制,请大家先看下面的一个应用场景: 
银行转账业务:
有一张银行账号表
create table account 
(id int primary key,
balance float);
现在有一段php程序,要完成把1号1元钱,转到2号账号上。
********模拟有转账错误的代码*******
<?php 
 //模拟出现转账业务的代码:
 $mysqli=new MySQLi("localhost","root","root","test"); 
 if (mysqli_connect_error()) {
  die('Connect Error '. mysqli_connect_error());
 }
 $sql1="update account set  balance=balance-1 where id=1";
 //这里我们模拟一个错误
 $sql2="update account2 set  balance=balance+1 where id=2";
 $res1=$mysqli->query($sql1);
 $res2=$mysqli->query($sql2);
 if(!$res1 || !$res2){
  echo '没有全部执行成功!';
 }
 $mysqli->close();
?>
     这时我们需要有一种方法来控制两句sql语句同时成功,同时失败的时候的处理。方法是使用事务控制来解决这个问题。
     如何进行事务控制,针对上一个实际问题,提出解决方案。新的概念: 事务的提交commit 和 事务的回滚 rollback。
<?php 
 //模拟出现转账业务的代码:
 $mysqli=new MySQLi("localhost","root","root","test"); 
 if (mysqli_connect_error()) {
  die('Connect Error '. mysqli_connect_error());
 }
 $mysqli->autocommit(false); 
 $sql1="update account set balance=balance-1 where id=1";
 //这里我们模拟一个错误
 $sql2="update account set balance=balance+1 where id=2";
 $res1=$mysqli->query($sql1);
 $res2=$mysqli->query($sql2);
 if(!$res1 || !$res2){
  echo '有语句执行失败,回滚!';
  $mysqli->rollback();//
 }else{
  echo '确定提交';
  $mysqli->commit();
 }
 $mysqli->close();
?>

在mysql控制台可以使用事务来操作,具体步骤如下:
1)开启一个事务:start transaction
2)做保存点:savepoint 保存点名称
3)操作....
4)可以回滚(也可以提交),如果没有问题就提交。
commit
 如果你觉得有问题,就回滚:rollback to 保存点。
事务的acid特性:原子性,一致性,持久性,隔离性。

五、mysqli扩展库增强--预处理 MySQLi_STMT 
    现在需要向mysql数据库添加100个用户,请问如何实现?
思路:
1. 发送100个 insert语句 ,频繁连接数据库和对sql语句编译都导致效率低下。
2. 一次性发送 100个insert语句,虽然只需要连接一次数据库,但是仍然要在数据库server编译多个sql语句,效率仍然低。
3. 使用预处理语句 MySQLi_STMT { (编译一次,执行多次)
使用预处理语句有什么好处?
与传统的执行sql语句相比有如下优点:效率高,执行速度快,安全性高,可以防止sql注入。
使用预处理语句快速入门案例:
执行dml 语句(没有结果集返回),需求: 请使用预处理的方式,向数据库添加三个用户。
执行dql 语句(有结果集返回):需求: 请使用预处理的方法,查询所有id>5的用户 的id,name,email,(id可能变化)。
需求: 请使用预处理的方式,查询id=4 密码 为 12345的用户信息,看看能否防止sql注入。
*******使用预处理语句完成dml******
<?php 
 $mysqli=new mysqli("localhost","root","root","test");
 if(mysqli_connect_errno()){
  die ('失败'.mysqli_connect_error());
 }
 $mysqli->query("set names utf8");
 $sql="insert into user1 (name,email,password) values(?,?,?)";
 $stm=$mysqli->prepare($sql); 
 //给?号绑定值
 $name="张三";
 $email="bayu@163.com";
 $password="123456";
 $stm->bind_param("sss",$name,$email,$password); 
 $b=$stm->execute(); 
 $name="张三2";
 $email="bayu2@163.com";
 $password="1234567";
 $b=$stm->execute();
 $name="张三3";
 $email="bayu3@163.com";
 $password="1234567";
 $b=$stm->execute();
 if($b){
  echo '成功!';
 }else{
  die('失败'.$stm->error);
 }
 $stm->close();
 $mysqli->close();
?>
*****使用预处理完成select语句dql********************
<?php 
 $mysqli=new mysqli("localhost","root","root","test");
 if(mysqli_connect_errno()){
  die ('失败'.mysqli_connect_error());
 }
 $mysqli->query("set names utf8");
 $sql="select id,name,email from user1 where id>?";
 $stm=$mysqli->prepare($sql) ; 
 //给?号绑定值
 $id=10;
 $stm->bind_param("i",$id); 
 //预处理执行时,返回bool,没有返回结果集对象,因此绑定结果到某变量
 $stm->bind_result($id,$name,$email);
 //执行
 $stm->execute();
 //取出结果集本身信息(可以不用讲解)
 $res=$stm->result_metadata();
 //var_dump($res);//$res 的类型就是 mysqli result
 while($field_info=$res->fetch_field()){
  
  echo "{$field_info->name}--";
 }
 echo "<br/>";
 //取出记录结果
 $stm->store_result();
 while($stm->fetch()){
  echo "<br/>$id--$name--$email";
 }
 $stm->free_result();
 $stm->close();
 $mysqli->close();
?>
*********查询用户id和密码,讲解预处理尅防止sql注入************************
<?php 
 $mysqli=new mysqli("localhost","root","root","test");
 if(mysqli_connect_errno()){
  die ('失败'.mysqli_connect_error());
 }
 $mysqli->query("set names utf8");
 $sql="select id,name,email from user1 where id=? and password=?";
 $stm=$mysqli->prepare($sql) ; 
 //给?号绑定值
 $id=1;
 $password="123456' or 1='1";
 $stm->bind_param("is",$id,$password); 
 //预处理执行时,返回bool,没有返回结果集对象,因此绑定结果到某变量
 $stm->bind_result($id,$name,$email);
 //执行
 $stm->execute();
 //取出结果集本身信息(可以不用讲解)
 $res=$stm->result_metadata();
 //var_dump($res);//$res 的类型就是 mysqli result
 while($field_info=$res->fetch_field()){
  
  echo "{$field_info->name}--";
 }
 echo "<br/>";
 //取出记录结果
 $stm->store_result();
 while($stm->fetch()){
  echo "<br/>$id--$name--$email";
 }
 $stm->free_result();
 $stm->close();
 $mysqli->close();
?>

使用预编译技术完成查询任务..-》如何封装..项目中说.
<?php
 //预编译演示
 //需求: 请使用预处理的方式,从数据库查询 
 //使用预处理的方法,查询所有id>5的用户 的id,name,email
 
 $mysqli=new MySQLi("localhost","root","hsp123","test");

if(mysqli_connect_error()){
  die(mysqli_connect_error());
 }

//创建一个预定义的对象 ?占位
 $sql="select id,name,email from user1 where id>?";
 $mysqli_stmt=$mysqli->prepare($sql);
 $id=5;
 //绑定参数
 $mysqli_stmt->bind_param("i",$id);
 //绑定结果集
 
 $mysqli_stmt->bind_result($id,$name,$email);
 //执行
 $mysqli_stmt->execute();
//取出绑定的值
 while($mysqli_stmt->fetch()){
  echo "<br/>--$id--$name--$email";
 }
 //还想执行另一个sql
 echo "<br/>***********************************";
 $id=10;
 //绑定参数
 $mysqli_stmt->bind_param("i",$id);
 //绑定结果集
 //执行
 $mysqli_stmt->execute();

//取出绑定的值
 while($mysqli_stmt->fetch()){
  echo "<br/>--$id--$name--$email";
 }
 //关闭资源
 //释放结果
 $mysqli_stmt->free_result();
 //关闭预编译语句
 $mysqli_stmt->close();
 //关闭连接
 $mysqli->close();
?>

现在我们看看mysqli的一些其他常用函数:

案例: 编写一函数,接收一个表名,然后把表头和表数据,显示页面
<?php
 function showTable($table_name){
  $mysqli=new MySQLi("localhost","root","hsp123","test");
  if(mysqli_connect_error()){
   die(mysqli_connect_error());
  }
  //$sql="select * from $table_name";
  $sql="desc user1";
  $res=$mysqli->query($sql);
  //如何获取返回总行数和列数
  echo "共有 行".$res->num_rows." -列=".$res->field_count;
  echo "<table border='1'><tr>";
  //如何取出表头,从$res取出
  while($field=$res->fetch_field()){
   echo "<th>{$field->name}</th>";
  }
  echo "</tr>";
  //循环取出数据
  while($row=$res->fetch_row()){
   echo "<tr>";
   foreach($row as $val){
    echo "<td>$val</td>";
   }
   echo "</tr>";
  }
  echo "</table>";
  //关闭资源
  $res->free();
  $mysqli->close();
 }
 showTable("user1");
?>

【推荐阅读】陈力:传智播客古代 珍宝币 泡泡龙游戏开发第39讲:PHP数据库编程MySQLi扩展库

陈力:传智播客古代 珍宝币 泡泡龙游戏开发第39讲:PHP数据库编程MySQLi扩展库相关推荐

  1. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口 如果一个类使用abstract 来修饰,则该类就是抽象类.抽象方法是声明为abstract的,是不需要实现的,供子类继承且实现 ...

  2. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第22讲:PHP语法、数据类型(整型、布尔型、浮点型、字符串型)

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第22讲:PHP语法.数据类型(整型.布尔型.浮点型.字符串型) PHP语法是什么样的,有哪些数据类型,有些什么变量.本文对PHP语法.数据类型(整型.布尔型 ...

  3. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第48讲:PHP绘图技术

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第48讲:PHP绘图技术 php绘图坐标体系中,坐标原点位于左上角,以像素为单位.php绘图时,要创建画布.画出各种图形.输出图形.销毁图形(释放内存资源). ...

  4. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第26讲:PHP函数

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第26讲:PHP函数 什么是PHP函数,如何通过function定义一个函数,如何理解函数的调用过程.这些问题都是网站建设中经常遇到的程序设计问题.在进行网站 ...

  5. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第28讲:PHP数组

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第28讲:PHP数组 PHP程序设计语言中的数组如何创建,一维数组的引用,PHP数组变量,foreach语句,如何对数组进行排序等等知识都是贵阳网站建设中的主 ...

  6. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第30讲:PHP多维数组

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第30讲:PHP多维数组 在PHP程序设计语言中,如何创建二维数组呢,怎样使用二维数组,这些问题在网站建设中非常重要.二维数组的基本语法为: $a=array ...

  7. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第50讲:PHP中的xml编程

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第50讲:PHP中的xml编程 Xml是extensiable markup language的简称,包括文档声明.元素.属性.注释.CDATA区.特殊字符 ...

  8. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十讲:深入理解盒子模型

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十讲:深入理解盒子模型 摘要:通过前节<第九讲:块元素.行内元素.标准流.盒子模型>学习了前节介绍了贵阳网站建设中的DIV+CSS中类选择器.i ...

  9. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第38讲:PHP数据库编程mysql

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第38讲:PHP数据库编程mysql php程序设计语言为我们提供了mysql扩展库.mysqli扩展库.Pdo三种方式来操作mysql数据库.本文为贵阳网站 ...

最新文章

  1. PAT (Advanced Level) 1014. Waiting in Line (30)
  2. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ << “ 操作符重载 | 使用集合中的 “ << “ 操作符添加一个元素 | 使用集合中的 “ << “ 操作符添加一个集合 )
  3. [原]Oracle数据文件损坏的模拟和修复(一) |ORA-01578 data block corrupted|
  4. Dubbo-Admin管理平台和Zookeeper注册中心的搭建(转)
  5. 倒水问题(Fill,UVA 10603) lrj白书 p202
  6. 介绍一个好用的日期倒计时工具
  7. linux自动挂载fcoe存储,在sdb上挂载USB 设备
  8. [Matlab] 不能在 syms 中假设 symfun 的值域
  9. 计算机中记录的意思,电脑日志看不懂,怎么才能知道日志记录的是什么意思啊?...
  10. 【SpringMVC】SpringMVC+Spring+hibernate整合
  11. 【linux】BootLoader简介(c语言编程)
  12. mysql大表数据抽取_从云数据迁移服务看MySQL大表抽取模式
  13. 10、Modules - LoadManual
  14. 面试题之Error和Exception总结
  15. 【动画演示软件】Focusky教程 | 加入 配音/录音/字幕
  16. 百度AI开放平台- API实战调用
  17. 从视频中提取光流 UCF-101
  18. 计算机网络的分类1:按网络拓扑结构分类,分为星型拓扑、环形拓扑、总线拓扑、树形拓扑、网状拓扑
  19. linux 多线程 semaphore ,Linux下多线程编程-Pthread和Semaphore使用.doc
  20. Android Studio中模拟器如何输入中文、将模拟器语言设置为中文

热门文章

  1. vue发布之后会出现白屏现象主要几种原因和解决办法
  2. 解决 Sniffer Pro 4.7 sp5 安装中有关JRE的问题
  3. 使用PyTorch构建GAN生成对抗网络源码(详细步骤讲解+注释版)01 手写字体识别
  4. iOS Category 添加属性实现原理 - 关联对象
  5. portainer拉取镜像报No such image: rejected
  6. 网络ID,广播地址,掩码位数计算
  7. ADB和Fastboot最新版的谷歌官方下载链接
  8. 键位修改工具RemapKey
  9. 大学计算机操作题模拟,大学计算机一级模拟操作题1
  10. sql-索引的作用(超详细),索引用法教程