前言

在实际的开发中,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( 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);
}
}

测试

<?php
require './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数据库,对于别的数据库没有办法操作。

更多相关文章

  1. 在线求助.Select语句包含ERP单据内表头与表身信息
  2. Spring 中jdbcTemplate 实现执行多条sql语句
  3. PB怎么将动态的sql语句以及数组。传给datawindow。
  4. 通过SQL语句访问远程数据库
  5. Access查找数据的SQL语句中,LIKE后面不可以用ESCAPE吗?
  6. mysql的几种SQL语句
  7. 如何用sql语句查询出当月的每日数据量
  8. 关系代数(Relation Algebra)与SQL语句的对应关系
  9. 写SQL语句,如何找到部分字段内容一样的两条记录?实现调货的功能

随机推荐

  1. Android 源码启动虚拟机经验
  2. 2011.07.11(2)——— android 自定义Notifi
  3. 笔记:Android Studio发布项目到Bintray
  4. Android(安卓)remake
  5. Android Socket Posix 实现
  6. adb 获取平台号
  7. Android 4.4报错,Android 7.0运行正常 Win
  8. layout_gravity="bottom" 失效
  9. 总结系列-Android的文件系统
  10. Anko:Android 代码动态布局的新方案