Go to comments

MySqli 扩展库

创建一个商品数据表

create database shopDB charset utf8;

use shopDB;

CREATE TABLE `products` (
  `id` mediumint unsigned NOT NULL AUTO_INCREMENT,
  `ishow` tinyint unsigned NOT NULL DEFAULT '0',
  `name` varchar(50) NOT NULL DEFAULT '0',
  `phone` varchar(50) NOT NULL DEFAULT '0',
  `intro` varchar(1500) NOT NULL DEFAULT '0',
  `time` varchar(50) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

CREATE TABLE `products` (
  `id` mediumint unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '0',
  `price` varchar(50) NOT NULL DEFAULT '0',
  `num` varchar(50) NOT NULL DEFAULT '0',
  `detail` varchar(500) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

truncate table products;


PHP5.0最主要的是将面向对象全面改写了,5.0以后增加功能,都会以对象的形式增加,

mysqli被封装在一个类中(i表示改进的意思),是一个面向对象对技,但也支持过程化的使用方式


window下安装mysqli扩展库

打开安装扩展的目录,每个扩展就是一个库 D:\xampp\php\ext\ 安装一个 php_mysqli.dll 文件

打开PHP配置文件 D:\xampp\php\php.ini ;extension=mysqli 把前面的分号去掉

重启服务器,通过 phpinfo


按照功能区分,mysqli扩展提供了三个类


1. MySQLi 和连接有关的类

主要控制PHP和mysql数据之间对链接、选择数据库、向mysql数据库服务器发生sql语句,以及设置字符集等等


2. Mysqli_result 处理结果集类

结果集就是用select语句从数据库中查询出来的,可以从结果集里面获取到记录信息、字段信息


以上两个类就可以完成前面mysql扩展的功能,而且效率更高、更稳定

第三个类就是mysqli新加的功能,我们通常叫预处理类


3. Mysqli_stmt 预处理类(后面重点介绍)

表达了一个准备好对语句


因为mysqli支持面向对象编程,也支持过程化的方式,所以手册上任何一个实例,都提供了面向对象的方法和过程化的两种方法

https://www.php.net/manual/zh/book.mysqli.php


处理数据都离不开下面几个步骤

1. 链接数据库

2. 选择数据库

3. 执行查询语句

4. 处理结果集


一、如何使用mysqli类

构造函数  mysqli()  连接数据库,链接成功返回 mysqli 对象

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306'); // 主机地址, 用户名, 密码, 数据库, 端口(可选)

var_dump($mysqli); // object(mysqli)#1 (18) { ... }


如果链接失败也返回 mysqli 对象,对象里面的两个属性(对象里有三个属性)

connect_errno  返回错误码,链接成功返回0

connect_error   返回错误信息

header('Content-Type: text/html; charset=utf-8');
error_reporting(0); // 防止出现 Warning: mysqli::__construct(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES) in

$mysqli = new mysqli('localhost', 'root', '错误密码', 'shopDB', '3306');

var_dump($mysqli); // object(mysqli)#1 (3)  { ... }

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error"; // Mysqli Link Error: 1045 Access denied for user 'root'@'localhost' (using password: YES)
  exit;
}

$mysqli->close(); // 脚本执行完,关闭链接


二个面向过程化的函数检查连接错误?

error_reporting(0);
$mysqli = new mysqli('localhost', 'root', '错误密码', 'shopDB', '3306');

if(mysqli_connect_errno()){ // 如果连接错误返回的是1045,进入判断

  echo mysqli_connect_errno(); // 返回链接错误号,链接失败返回1045,链接正确返回 0

  echo mysqli_connect_error(); // 返回错误信息的 

  $mysqli = null; // 把 mysqli对象赋值为null,就不是对象了

  exit;
}


 select_db('dbname')  在程序执行过程中切换数据库

$mysqli = new mysqli('localhost', 'root', '', '', '3306');

$mysqli->select_db('dbshop'); // 创建mysqli对象时不写数据库或写了默认的库,可以在程序执行过程中切换数据库

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$mysqli->close();


mysqli_init(void) 还有一种连接数据库的方式

$mysqli = mysqli_init(); // 返回一个mysqli对象

// 可以设置选项优化 
// https://www.php.net/manual/zh/mysqli.options.php
// options( in option, mixed value ) 

$mysqli->real_connect('127.0.0.1', 'root', '', 'shopDB'); // 连接数据库

if($mysqli->connect_errno){
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}else{
  echo '链接成功';
}

$mysqli->close();


获取服务器端、客户端信息的方法/属性

character_set_name()  获取当前字符集(mysql用的什么字符集)

get_client_info()  获取mysql客户端的信息

host_info  主机信息

protocol_version  协议的版本

server_info  服务器的信息

server_version  服务器的版本

info  获取最近执行的查询信息(还没测试这个)

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306');

echo $mysqli->character_set_name().'<br/>'; // utf8mb4

echo $mysqli->get_client_info().'<br/>'; // mysqlnd 7.4.20

echo $mysqli->host_info.'<br/>'; // localhost via TCP/IP

echo $mysqli->protocol_version.'<br/>'; // 10

echo $mysqli->server_info.'<br/>'; // 5.5.5-10.4.19-MariaDB

echo $mysqli->server_version.'<br/>'; // 100419

echo $mysqli->info.'<br/>'; // 

$mysqli->close();


如何执行sql语句?


执行sql语句的方式有多种

1. query() 执行sql语句(最常用的)

2. prepare() 准备执行一个sql查询语句

3. multi_query() 执行多个查询语句


sql语句又分两种,

1. 一种是select语句有结果集

2. 还有一种非select语句会影响行数


queyr()方法发送sql语句到数据库并且执行

1. 非select语句返回bool类型,成功返回真/失败返回假

2. select语句返回结果集对象


通过Mysqli对象里面的两个属性,获取错误信息?

errno 获取错误号

error 获取错误信息


提示的错误

字段写错了   1054 | Unknown column 'xxx' in 'field list'  未知的列 xxx 在字段列表里面

表名写错了   1146 | Table 'shopdb.productsxxx' doesn't exist  表名productsxxx不存在 把表名称写错


 query( string query, [, int resultmode] )  只传一个sql语句参数就行了

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306');

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql = "insert into products(id, name, price, num, detail)values(null, 'HUAWEI', '6000', '300', 'HarmonyOS操作系统')";

$result = $mysqli->query($sql);

var_dump($result); // bool(true)(非select语句返回布尔类型)

if(!$result){
  echo "sql语句有误 $mysqli->errno | $mysqli->error";
  exit;
}

$mysqli->close();


循环插入 80 条数据

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306');

$products = ['华为', '小米', '苹果', 'oppo', 'vivo'];
$detail = ['双卡双待', '4G', '快速充电', '无线充电', '硬件配置高', '像素高'];

for($i = 0; $i < 80; $i++){
  $sql = "insert into products(id, name, price, num, detail)values(null, '".$products[rand(0, 4)]."', '".rand(10000, 1999)."', '".rand(200, 10)."', '".$detail[rand(0, 5)]."')";
  $result = $mysqli->query($sql);
  echo "插入 $i 成功<br>";
}

$mysqli->close();


非select语句执行成功,会有影响的行数


删除语句影响行数

1. 第一次刷新,删除多行,影响多行

2. 再刷新一次影响0条,sql 语句本身没有错,只是没有满足条件的记录而已,所以可以判断影响的行数大于0,才是真正的删除成功或修改成功了

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306');

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql = "delete from products where id > '60'";

$result = $mysqli->query($sql);

if(!$result){
  echo "sql语句有误 $mysqli->errno | $mysqli->error";
  exit;
}

if($mysqli->affected_rows > 0){
  echo "删除语句成功,影响 $mysqli->affected_rows 行";
}else{
  echo '没有行数被影响';
}

$mysqli->close();


insert_id  属性获取最后自动增长的id列

$mysqli = new mysqli('localhost', 'root', '', 'shopDB', '3306');

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql = "insert into products(id, name, price, num, detail)values(null, 'HUAWEI', '6000', '300', 'HarmonyOS操作系统')";

$result = $mysqli->query($sql);

if(!$result){
  echo "sql语句有误 $mysqli->errno | $mysqli->error";
  exit;
}

if($mysqli->affected_rows > 0){
  echo "影响 $mysqli->affected_rows 行<br/>";
}

echo "最后增长的ID ", $mysqli->insert_id; // 获取最后自动增长的id列

$mysqli->close();


二、处理结果集

mysqli三个类中 mysqli_result 专门处理 select 语句后返回的结果集


结果集主要处理两方面

1. 处理记录,就是把记录一条一条的读取出来

2. 处理字段信息,如何把结果集中列(字段)信息,比如列名、列的属性获取到


执行 select 查询语句,返回的是结果集,在这里结果集就是一个对象

header('Content-Type: text/html; charset=utf-8');

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql ="select * from products";

$result = $mysqli->query($sql); // 返回的结果集是一个对象

if(!$result){
  echo "Sql语句错误: $mysqli->errno $mysqli->error";
  exit;
}

var_dump($result); // object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(5) ["lengths"]=> NULL ["num_rows"]=> int(69) ["type"]=> int(0) }

$result->close(); // 释放结果集

$mysqli->close();

按过程化来说,结果集也是一种资源,所以也需要释放,下面三个方法用那个都可以

free()

close()

free_result()


有了这个结果集对象,下面是结果集对象中的方法和属性,我们可以从结果集里面获取任意信息


方法

close()

data_seek()   指定从第几条数据开始获取数据

fetch_array() 返回记录,参数(MYSQL_ASSOCI, MYSQLI_NUM, MYSQLI_BOTH,默认是第三个)

fetch_assoc() 返回记录,关联数组的方式

fetch_field() 获取列信息

fetch_fields()

fetch_field_direct()

fetch_object()返回记录,对象的形式

fetch_row()   返回记录,索引数组的形式

field_seek()  字段(列)移动指针的

free_result()


属性

current_field  获取当前列的列号

field_count  获取结果集中的列数,有几个字段

lengths 返回当前列中字段的长度

num_rows  获取结果集中的行数,共有多少条数据

type


1、获取记录信息

获取行数和列数

num_rows属性,结果集中共有多少条数据

field_count属性,结果集中的列数,就是有几个字段(这个和下面获自段信息有点联系)

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql ="select id, name from products where id < 50"; // 查询2个字段加一个where条件限制,会影响取到的行数和列数

$result = $mysqli->query($sql);

if(!$result){
  echo "Sql语句错误: $mysqli->errno $mysqli->error";
  exit;
}

$rows = $result->num_rows; // 获取结果集中的行数
$cols = $result->field_count; // 获取结果集中的列数(列的个数和下面)
echo "数据表中有{$rows}行,{$cols}列"; // 数据表中有49行,2列

$result->close(); // 关闭结果集
$mysqli->close();


fetch_assoc() 返回关联数组,下标就是列名

data_seek(5) 移动指针

close() 释放结果集


获取记录信息有四个方法

fetch_row() 返回索引数组

fetch_assoc() 返回关联数组,下标就是列名

fetch_array() 两个数组都返回,参数(MYSQL_ASSOC, MYSQLI_NUM, MYSQLI_BOTH默认是第三个)

fetch_object() 返回对象


每执行一次,会从结果集中取出当前一条记录(默认当前记录就是第一行)。可以使用 data_seek(5) 方法指定,5表示默认从第五行记录开始取

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql ="select * from products";

$result = $mysqli->query($sql);

if(!$result){
  echo "Sql语句错误: $mysqli->errno $mysqli->error";
  exit;
}

$assoc = $result->fetch_assoc(); // 每执行一次,从结果集中取出当前一条记录
print_r($assoc); // Array ( [id] => 1 [name] => vivo [price] => 7008 [num] => 48 [detail] => 快速充电 )

$result->close();
$mysqli->close();


每次取出一行,指针指向下一行,下次再取时就会在取出下一行,当结果集中没有记录时返回false,所以可以用循环取出数组

header('Content-Type: text/html; charset=utf-8');

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$sql ="select * from products";

$result = $mysqli->query($sql);

if(!$result){
  echo "Sql语句错误: $mysqli->errno $mysqli->error";
  exit;
}

// 每循环一次换一行,当最后一条获取不到时,返回false退出循环,正常的情况下返回数组,数组会当成true来处理
if($result = $mysqli->query($sql)){
  while($rows = $result->fetch_assoc()){
    echo "<br/>";
    print_r($rows);
  }
}

$result->close();
$mysqli->close();


用表格的形式打印出来

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

if ($mysqli->connect_errno) {
  echo "Mysqli Link Error: $mysqli->connect_errno $mysqli->connect_error";
  exit;
}

$result = $mysqli->query("select * from products");

$result->data_seek(50); // 从结果集里面移动到第5行开始取数据,实际是从第6个开始显示

if(!$result){
  echo "Sql语句错误: $mysqli->errno $mysqli->error";
  exit;
}

echo '<table border="1" align="center" width="900">';

  while($rows = $result->fetch_assoc()){

    echo '<tr>';
    // 可以用便利
    // foreach($rows as $val){
    // 	echo "<td>{$val}</td>";
    // }

    // 也可以一行一行的写出每个单元
    echo "<td>{$rows['id']}</td>
    <td>{$rows['name']}</td>
    <td>{$rows['price']}</td>
    <td>{$rows['detail']}</td>";
    echo '</tr>';
  }

echo '</table>';

$result->close();
$mysqli->close();


2、获取字段(列)信息

 fetch_field()  方法获取列信息

1. 获取完一列,指针往下走一次

2. 返回来的是一个对象,通过这个对象我们能获取

    name 列名

    orgname 列的原名(因为列可以起别名)

    table 表名

    orgtable 原表名

    max_length 最大长度,字段值的最大列的长度

    length 长度

    charsetnr 字符集

    type 类型


只获取列的名称(name)和列长度(max_length)

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

$result = $mysqli->query("select * from products where id <= 3");

echo '<table border="1" align="center" width="900">';
echo '<tr>';
// 一共有5列自动循环五列,到最后一列返回false就结束循环了
while($field = $result->fetch_field()){
  echo "<th>{$field->name} - {$field->max_length}</th>"; // 返回来一个对象$field,在对象里$field里获取列名称和列长度
}
echo '</tr>';

while($rows = $result->fetch_assoc()){
  echo '<tr>';
  echo "<td>{$rows['id']}</td>
  <td>{$rows['name']}</td>
  <td>{$rows['price']}</td>
  <td>{$rows['num']}</td>
  <td>{$rows['detail']}</td>";
  echo '</tr>';
}
echo '</table>';

$mysqli->close();


fetch_fields() 方法

1. 一次性把所有列全取过来了,然后形成一个数组,

2. 数组里面每一个成员,就是每一个列的对象

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");
$result = $mysqli->query("select * from products where id < 10");

$field = $result->fetch_fields(); // 这里不用循环,把所有列都取出来
print_r($field); // 便利这个数组就可以了

$mysqli->close();


上面说过 data_seek() 方法可以移动记录的指针,这里的 field_seek() 方法可以移动字段的指针


 lengths  属性是结果集对象的属性,返回当前列中单个字段的长度

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

$result = $mysqli->query("select * from products where id < 10");

echo '<table border="1" align="center" width="900">';
while($rows = $result->fetch_assoc()){
  echo "<tr>
    <td>[{$result->lengths[0]}]-{$rows['id']}</td>
    <td>[{$result->lengths[1]}]-{$rows['name']}</td>
    <td>[{$result->lengths[2]}]-{$rows['price']}</td>
    <td>[{$result->lengths[3]}]-{$rows['num']}</td>
    <td>[{$result->lengths[4]}]-{$rows['detail']}</td>
  </tr>";
}
echo '</table>';

$mysqli->close();


current_field 是结果集对象的属性,获取当前列的列号

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

$result = $mysqli->query("select * from products where id < 10");

echo '<table border="1" align="center" width="900">';

echo '<tr>';
while($field = $result->fetch_field()){
  // current_field属性是结果集里面的属性,作用是返回当前列的列号
  echo "<th>{$result->current_field}_{$field->name} - {$field->max_length}</th>"; 
}
echo '</tr>';

while($rows = $result->fetch_assoc()){
  echo '<tr>';
  echo "<td>{$rows['id']}</td><td>{$rows['name']}</td><td>{$rows['price']}</td><td>{$rows['num']}</td><td>{$rows['detail']}</td>";
  echo '</tr>';
}

echo '</table>';

$mysqli->close();


sql语句查看表结构  desc products  可以看到那个是主键,那个是唯一索引,那个字段是否为空,下面通过该语句获取表的详细信息

$mysqli = new mysqli("localhost", "root", "", "shopdb", "3306");

$result = $mysqli->query("desc products"); // 通过该sql语句获取表信息

echo '<table border="1" align="center" width="900">';
echo '<tr>';

while($field = $result->fetch_field()){
  echo "<th>{$field->name}</th>";
}

echo '</tr>';

while($rows = $result->fetch_assoc()){
  echo '<tr>';
  foreach($rows as $val){
    echo "<td>{$val}</td>";
  }
  echo '</tr>';
}

echo '</table>';

$mysqli->close();






Leave a comment 0 Comments.

Leave a Reply

换一张