前言

在实际的开发中,PHP都是会和数据库一起使用的,因为在后台需要有太多的数据进行保存,而数据库就是一种很好的保存数据的地方,我们PHP开发用到的数据库是关系型数据库mysql,而PHP和mysql数据库只有连接,我们才能通过php代码对数据库进行操作。

MySqli

PHP的开发离不开数据库,而在PHP中可以通过MySQLi连接数据库的。但是MySQLi只能连接mysql数据库。同时mysqli是一种面向对象的技术。

MySQLi的特点:

  • 效率提高,稳定性强。
  • 对数据库进行操作。
  • 支持面向对象开发。同时也支持面向过程开发。

想要在PHP中使用MySQLi功能需要在php.ini中加载php_mysql.dll这个动态连接文件。

操作流程

  1. 在mysql中创建一个数据库当做操作对象。
  2. 打开PHP扩展库
  3. 创建mysqli的对象

    $mysql = new MySQLi(主机,账号,密码,数据库,端口号);
    

    里面有几个参数。

  4. 设置字符集

    $mysql -> set_charset('utf8');
    
  5. 编写sql语句并且执行。这个sql语句可以是dml,dql语句

    $mysql -> query($sql);
    
  6. 将取回的结果显示页面取出数据有四种方式(assoc、row、object、array)我们一般使用assoc这种方式。但是如果是dml语句则返回布尔值。

    $res -> fetch_assoc();
    
  7. 释放结果集。关闭连接。

    $res -> free();
    $mysqli -> close();
    

当我们在进行插入,删除,修改(dml)时,返回的是一个布尔值,但是我们并不知道里面有没有变化。可以用$mysqli -> affected_rows,mysqli里面的属性进行判断,返回的结果是sql语句对数据表的影响行数。

<?php//使用面向对象进行数据库的连接,在创建对象的时候就自动的连接数据$mySQLi = new MySQLi('localhost','root','123456','test',3306);//判断数据库是否连接if($mySQLi -> connect_errno){die('连接错误' . $mySQLi -> connect_error);}//设置字符集$mySQLi -> set_charset('utf8');//编写sql语句并执行$sql = "select * from good";//发送sql语句并执行,如果是select语句,返回的是一个对象,其他的返回来一个boolean.$res = $mySQLi -> query($sql);echo '<pre>';//使用$res对象里面的fetch_assoc()取出里面的数据.// while($row = $res->fetch_assoc()){//  var_dump($row);// }// 使用fetch_row()方法// while($row = $res -> fetch_row()){//  var_dump($row);// }//使用fetch_array();// while($row = $res -> fetch_array()){//  var_dump($row);// }//fetch_object();while($row = $res -> fetch_object()){var_dump($row);}$res -> free();$mySQLi -> close();

上面的代码就是使用mysqli的具体实现。mysqli是使用面向对象的思想来写的。关于其中的方法。

  • $mySQLi -> connect_errno返回连接的最后一次连接的错误,如果返回0则连接成功,返回非0则连接失败

  • $mySQLi -> connect_error返回连接错误的原因。

  • $mySQLi -> set_charset(‘utf8’);设置字符集,里面的参数根据自己的情况写。

  • mySQLi−>query(mySQLi -> query(sql)当写完一个sql语句后,使用这个方法传递sql语句到数据库执行。并且根据sql语句的类型不同,返回不同的结果上面返回的是一个mysqli_result对象

  • mysqli_result对象代表从一个数据库查询中获取的结果集。也就是进行sql查询从数据库中返回的结果。得到里面的结果mysqli/_result对象提供了四种方法,他们有不同的区别。

    1. $mysqli_result -> fetch_assoc()返回结果集中的一条数据,这条数据是一个关联数组,键是数据库表的字段名,值是表里面的值。

      array(3) {["id"]=>string(1) "1"["name"]=>string(6) "张三"["price"]=>string(7) "1234.60"
      }
      
    2. $mysqli_result -> fetch_row()返回的也是结果集中的一条数据,这条数据是一个索引数组。

      array(3) {[0]=>string(1) "1"[1]=>string(6) "张三"[2]=>string(7) "1234.60"
      }
      
    3. $mysqli_result = $res -> fetch_array()返回的一个数组,是一个关联数组和索引数组组合的数组。

      array(6) {[0]=>string(1) "1"["id"]=>string(1) "1"[1]=>string(6) "张三"["name"]=>string(6) "张三"[2]=>string(7) "1234.60"["price"]=>string(7) "1234.60"
      }
      
    4. $mysqli_result = $res -> fetch_object()返回一个有一条数据封装成的对象。这个对象是使用了PHP的内置标准类。表的字段是类的属性。

      object(stdClass)#3 (3) {["id"]=>string(1) "1"["name"]=>string(6) "张三"["price"]=>string(7) "1234.60"
      }
      

mysqli的事务处理

mysqli处理mysql的事务一共提供了三种方式开启事务。

  • $mySQLi -> query(‘start transaction’);
  • $mySQLi -> query(‘set autocommit = false’);
  • $mySQLi -> begin_transaction();

    <?php//使用面向对象进行数据库的连接,在创建对象的时候就自动的连接数据$mySQLi = new MySQLi('localhost','root','123456','test',3306);//判断数据库是否连接
    if($mySQLi -> connect_errno){die('连接错误' . $mySQLi -> connect_error);
    }
    //设置字符集
    $mySQLi -> set_charset('utf8');//编写sql语句
    $sql1 = "insert into good values(null,'武松',2345.7)";
    $sql2 = "update good set price = 3546.67 where id = 2";//开启事务
    $mySQLi -> query('start transaction');
    // $mySQLi -> query('set autocommit = false'); //第二种方式
    // $mySQLi -> begin_transaction();//第三种方式//发送sql语句,因为sql语句是插入和修改语句,返回的结果是一个布尔值。
    $res1 = $mySQLi -> query($sql1);
    $res2 = $mySQLi -> query($sql2);if($res1 && $res2){echo '操作成功';//提交事务。$mySQLi -> commit();
    }else{echo '操作失败';//进行数据的回滚$mySQLi -> rollback();
    }$mySQLi -> close();
    

当语句执行失败的时候可以进行数据的回滚。

mysqli批量执行sql语句

在用PHP操作数据库时,有时候我们需要一次性执行多条sql语句,比如批量增加用户,这时如果单条单条的向mysql数据库发送sql指令,效率不高,这时可以考虑使用批量执行sql语句的方式。

mysqli批量执行sql语句的语法:

$sql = "sql语句1;sql语句2;sql语句3";
$res = $mysqli -> multi_query();

当然对于批量操作,有不同的返回结果。

  1. 如果批量执行的是dml操作语句,那么 返回结果是布尔值
  2. 如果批量执行的是dql(select)操作语句,那么 返回结果是多个结果集.

批量执行dml语句

<?php//使用面向对象进行数据库的连接,在创建对象的时候就自动的连接数据$mySQLi = new MySQLi('localhost','root','123456','test',3306);//判断数据库是否连接if($mySQLi -> connect_errno){die('连接错误' . $mySQLi -> connect_error);}//设置字符集$mySQLi -> set_charset('utf8');$sql = "insert into good values(null,'孙悟空',1234.8);";$sql .= "insert into good values(null,'猪八戒',4564.3)";//进行批量的sql语句执行。$res = $mySQLi -> multi_query($sql);if($res){echo '添加成功';}else{echo '添加失败' . $mySQLi -> error;}$mySQLi -> close();

在进行dml批量操作时,如果有一个语句错误,那么后面的sql语句就不执行了,并且在进行dml批量操作时,返回的布尔值的结果,就是第一条sql语句执行的结果。那么如果第一条语句执行成功,后面的语句执行失败,得到的布尔值也是true。

批量执行dql语句

<?php//使用面向对象进行数据库的连接,在创建对象的时候就自动的连接数据$mySQLi = new MySQLi('localhost','root','123456','test',3306);//判断数据库是否连接if($mySQLi -> connect_errno){die('连接错误' . $mySQLi -> connect_error);}//设置字符集$mySQLi -> set_charset('utf8');$sql = 'select id,name from good;';$sql .= 'select price from good';echo '<pre>';//这里返回的记过是一个布尔值。if($mySQLi -> multi_query($sql)){//得到里面的数据do{//通过这个函数返回查找的结果集,返回的是一个mysqli_result对象。$res = $mySQLi -> store_result();while($row = $res -> fetch_assoc()){var_dump($row);}//判断是否还有结果。如果没有退出循环。if(!$mySQLi -> more_results()){break;}//相当于一个指针,指向下一个结果。}while($mySQLi -> next_result());}else{echo '执行失败';}$mySQLi -> close();

当执行的批量语句是dql语句时,数据库会返回查找的结果。通过mysqli -> store_result()这个方法返回mysqli->result对象。上面的代码中批量执行了两句select,数据库会返回两个结果集,而通过store_result()方法返回的是一条select语句的结果。当显示完数据后通过more_results()方法进行判断是否还有数据。如果没有,跳出循环。有数据的话通过next_result()方法指向下一个结果集。

more_results()方法是判断有没有下一个结果集,但是结果集的指针并不会执行下一个结果集。而next_result()方法是把指针向前挪移一位。

mysqli预处理技术

在PHP操作数据库中使用预处理技术可以大大提高我们的sql语句执行速度。关于sql语句在dbms中的执行时间消耗的步骤如图:

在其中dbms进行分析sql语句的时间大约占20%,而预处理就是把分析sql语句这个步骤省略,从而提高执行sql语句效率。预处理就是通过把我们想传入的参数使用占位符?来表示,通过预处理对象绑定真实的参数。

<?php//使用面向对象进行数据库的连接,在创建对象的时候就自动的连接数据$mySQLi = new MySQLi('localhost','root','123456','test',3306);//判断数据库是否连接if($mySQLi -> connect_errno){die('连接错误' . $mySQLi -> connect_error);}//设置字符集$mySQLi -> set_charset('utf8');$sql = "INSERT INTO good VALUES(?,?,?)";//通过prepare()方法返回一个预处理的对象。$mysql_stmt = $mySQLi -> prepare($sql);$id = 18;$name = '松江';$price = 2344.45;//绑定参数$mysql_stmt -> bind_param('iss',$id,$name,$price);//通过预处理对象执行。if($mysql_stmt -> execute()){echo '执行成功';}else{echo '执行失败';}//当我们还想添加一条数据时,dbms不用分析sql语句。$id = 19;$name = '武松';$price = 2346.45;//绑定参数,$mysql_stmt -> bind_param('iss',$id,$name,$price);//通过预处理对象执行。if($mysql_stmt -> execute()){echo '执行成功';}else{echo '执行失败';}

在上面的代码中,通过mysqli -> prepare()方法得到预处理对象,而sql语句里面的参数是通过占位符?表示。得到预处理对象后通过定义想传递的参数,使用bind_param()方法进行参数的绑定。然后通过execute()方法进行执行,之后如果执行同样的参数,只要把参数定义完之后,进行绑定执行就行了。

bind_param(参数1,参数2):这个方法是绑定参数的方法,里面一共有两个参数,第一个参数是我们绑定参数的类型,我们一般用到三个值:

  • i int类型
  • d double类型,也就是小数类型
  • s 字符串类型
    第二个参数是对象第一个参数的变量的值。

上面的是插入的时候时候预处理,在dml,dql都可以使用预处理。

DaoMysqli.class.php开发

PHP是面向对象的语言,而在操作数据库时,我们可以把一些功能进行封装,创建成对象。使用DaoMySqli这个封装好的类,可以简化我们的项目,体现面向对象的思想。

DaoMysqli.class这个类的实现:

  1. 使用单例模式控制资源,始终只有一个对象。
  2. 使用final关键字修饰类防止被继承。
  3. 使用魔术方法__clone(),防止克隆。
  4. 通过在类里面创建mysqli对象,连接数据库。
  5. 通过mysqli在类里面进行数据的增删改查等操作,把操作过程封装起来。

单例模式

//把构造函数私有化,在类外部创建不了对象。private function __construct($canshu){$this -> initMySQLi($canshu);}public static function getInstrance($canshu){if(!(self::$daoMysqli instanceof DaoMysqli)){self::$daoMysqli = new DaoMysqli($canshu);}return self::$daoMysqli;
}

把构造函数私有化,在类外面不能创建对象。同时提供一个创建对象的静态方法,在静态里面创建DaoMysqli对象和mysqli对象。

防止继承、克隆

//防止继承。
final class DaoMysqli{
//防止克隆。
private function __clone(){}

创建mysqli对象

//初始化mysqli对象。private function initMySQLi($canshu){$this -> host = isset($canshu[0]) ? $canshu[0] : '';$this -> user = isset($canshu[1]) ? $canshu[1] : '';$this -> password = isset($canshu[2]) ? $canshu[2] : '';$this -> db_name = isset($canshu[3]) ? $canshu[3] : '';//如果端口号没有传入,默认是3306//编码默认是utf8。$this -> duankou = isset($canshu[4]) ? $canshu[4] : 3306;$this -> charset = isset($canshu[5]) ? $canshu[5] : 'utf8';if($this -> host == '' || $this -> user == '' || $this -> password == '' || $this -> db_name == ''){die('参数不能为空');}$this -> mySQLi = new MySQLi($this -> host,$this -> user,$this -> password,$this -> db_name,$this -> duankou);if($this -> mySQLi -> connect_errno){die('连接错误,错误信息是' . $this -> mySQLi -> connect_error);}$this -> mySQLi -> set_charset($this -> charset);}

在类里面通过调用私有的构造函数进行对象的创建。

通过mysqli对象操作数据库

//dql操作返回一个数组。public function mySelect($sql){if($res = $this -> mySQLi -> query($sql)){$res = $this -> mySQLi -> query($sql);$rows = array();while($row = $res -> fetch_assoc()){$rows[] = $row;}return $rows;}else{die('错误,' . $this -> mySQLi -> error);}}//dml操作。public function dml($sql){return $this -> mySQLi -> query($sql);}

当时dql语句时,可以在方法里面进行处理,直接把数据解析出来,放到一个数组里面进行返回。

源代码

<?php
final class DaoMysqli{private static $daoMysqli; //类本身对象private $mySQLi; //mysqli对象,在类里面操作数据库。private $host; //主机名private $user;//用户名private $password;//密码private $db_name;//数据库名字private $duankou; //数据库占用的端口号。private $charset; //使用的字符集//把构造函数私有化,在类外部创建不了对象。private function __construct($canshu){$this -> initMySQLi($canshu);}//初始化mysqli对象。private function initMySQLi($canshu){$this -> host = isset($canshu[0]) ? $canshu[0] : '';$this -> user = isset($canshu[1]) ? $canshu[1] : '';$this -> password = isset($canshu[2]) ? $canshu[2] : '';$this -> db_name = isset($canshu[3]) ? $canshu[3] : '';//如果端口号没有传入,默认是3306//编码默认是utf8。$this -> duankou = isset($canshu[4]) ? $canshu[4] : 3306;$this -> charset = isset($canshu[5]) ? $canshu[5] : 'utf8';if($this -> host == '' || $this -> user == '' || $this -> password == '' || $this -> db_name == ''){die('参数不能为空');}$this -> mySQLi = new MySQLi($this -> host,$this -> user,$this -> password,$this -> db_name,$this -> duankou);if($this -> mySQLi -> connect_errno){die('连接错误,错误信息是' . $this -> mySQLi -> connect_error);}$this -> mySQLi -> set_charset($this -> charset);}//防止克隆。private function __clone(){}public static function getInstrance($canshu){if(!(self::$daoMysqli instanceof DaoMysqli)){self::$daoMysqli = new DaoMysqli($canshu);}return self::$daoMysqli;}//dql操作返回一个数组。public function mySelect($sql){if($res = $this -> mySQLi -> query($sql)){$res = $this -> mySQLi -> query($sql);$rows = array();while($row = $res -> fetch_assoc()){$rows[] = $row;}return $rows;}else{die('错误,' . $this -> mySQLi -> error);}}//dml操作。public function dml($sql){return $this -> mySQLi -> query($sql);}
}

测试

<?phprequire './DaoMysqli.php';$canshu = array('localhost','root','123456','test','3306');$dao = DaoMysqli::getInstrance($canshu);$sql = "select * from good";$res = $dao -> mySelect($sql);foreach ($res as $value) {var_dump($value);echo '<br>';}

参数是通过一个数组传进去的。

总结

PHP操作数据库的方法中很多中,mysqli只是其中的一种,这种操作方式我们更容易理解和掌握,但是mysqli还是有一些不足,我们在PHP开发中有时候使用的数据库并不是mysql数据库,而是别的数据库,这时,mysqli这种方式就显得有些无力,mysqli只是纯粹的操作mysql数据库,对于别的数据库没有办法操作。

PHP基础教程十四之使用MySqli操作数据库相关推荐

  1. MySqli操作数据库

    mysqli 操作分为面向对象,面向过程两种. 1. PHP基础教程十四之使用MySqli操作数据库 2. mysqli 操作数据库 3. MySQLi基于面向过程的编程 转载于:https://ww ...

  2. Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议

    Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议 原文:Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议 在上一篇中,留下了许可协议的问题,目前已经解决.感谢网友武全的指点 ...

  3. 【Visual C++】游戏开发笔记四十六 浅墨DirectX教程十四 模板测试与镜面特效专场

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处.   文章链接: http://blog.csdn.net/zhmxy555/article/details/8632184 作者:毛星云( ...

  4. Cesium教程(十四):简易三维模型的可视化

    Cesium教程(十四):简易三维模型的可视化 效果预览 1.高效三维数据格式:3D Tiles 3D Tiles是Cesium提出的处理三维地理大数据的数据格式,目前已是OGC数据标准之一,并在We ...

  5. go设置后端启动_Go语言基础(十四)

    Go语言基础(十四) 一.Redis 二.NSQ 三.Go module 四.Context......0 一.Redis Redis是一个key-value存储系统.和Memcached类似,它支持 ...

  6. matlab最基础教程(四):常用的系统自带函数,符号变量与字符串篇

    matlab最基础教程(四):常用的系统自带函数,符号变量与字符串篇 前言:matlab字面意思是矩阵实验室,软件重点是数值变量的运算.所以在符号变量和字符串的运算上,功能并不强大,我用的也不是很多, ...

  7. akka学习教程(十四) akka分布式实战

    akka系列文章目录 akka学习教程(十四) akka分布式实战 akka学习教程(十三) akka分布式 akka学习教程(十二) Spring与Akka的集成 akka学习教程(十一) akka ...

  8. python基础教程书在线阅读_python基础教程第四版

    第四版 pdf电子书是一部非常实用的python编程语言学习的电子书籍,无论你是刚接触编程或者刚接触Python,通过这部电子书就能让你快速入门,感兴趣的朋友欢迎来绿色资源网免费下载阅读. pytho ...

  9. Java SE基础(十四)常用API

    Java SE基础(十四)常用API 概述 Object类 构造方法 成员方法 toString()方法 equals(Object obj)方法 Arrays排序 Arrays类概述 Arrays成 ...

最新文章

  1. RESTful之限流Throttling
  2. webpack原理探究 打包优化
  3. batchsize一定是2的幂_支付接口的幂等性设计
  4. sap abap好用的函数
  5. Logistic Regression Classifier逻辑回归
  6. 王垠:怎样尊重一个程序员?
  7. Python basestring函数- Python零基础入门教程
  8. [转]Linux内核基础与常用命令总结
  9. Python与C:指针与按址传递
  10. python_numpy_求L1损失的两种方法
  11. windows权限了解
  12. 一键清理windows系统垃圾|临时文件bat脚本
  13. PS的钢笔,路径,选取,描边(虚线)
  14. c语言实现图片轮播,纯css实现轮播图
  15. 大数据工程师入职京东年薪37w(附:面试真题分享)
  16. C++图书管理系统及相应文件的创建与输出
  17. api是什么意思?又该如何使用呢?
  18. H5新增表单元素、控件
  19. Opserver 初探三《服务器数据监控》
  20. 洛谷4168 [Violet]蒲公英

热门文章

  1. 继承有什么安全缺陷?
  2. django model中的save()方法--model的主键pk
  3. FlyTreeView V4.3 破解手记
  4. the following arguments are required: --input/-i
  5. dancing links x(舞蹈链算法)详解
  6. STM32CUBEMX(13)--SPI,W25Q128外部Flash移植
  7. three Quaternion 源码解读
  8. R语言:平稳性的检验1
  9. 百度下线搜索快照功能,内部人士:因技术升级导致功能淘汰;法国App开发者集体起诉苹果;Linux 5.19 发布|极客头条
  10. 嵌入式工程师专业知识与技能