Mysql扩展(基于PHP7)
PHP 针对 MySQL 数据库操作提供的扩展:允许PHP当做MySQL的一个客户端连接服务器进行操作。
PDO或mysqli都可以连接mysql,但更推荐使用PDO连接数据库,因为PDO支持12种不同的数据库驱动程序,mysqli只支持mysql,而且PDO性能更高
;php.ini中的 MySQL 扩展
extension=mysqli
🌈PHP7对比PHP5的MySQL操作上改动很大,但是仍旧有迹可循、有规律:🌰
PHP5:
mysql_query('use examples');
PHP7:
mysqli_query($conn,'use examples');
可见,7中在 mysql命令后面多了个'i',并且传参的时候都要传入 $conn 连接对象 , 另外对于
mysqli_num_rows($res) 等增删改查以下的方法,只是把 mysql 改成 mysqli 即可。
🌈MySQL8.0和PHP7.13 兼容性问题
官方人员解释👉https://mysqlserverteam.com/upgrading-to-mysql-8-0-default-authentication-plugin-considerations/
caching_sha2_password 问题 👉 https://blog.csdn.net/maoxinwen1/article/details/88629313
授权问题https://www.2ita.com/thread-27166-1-1.html
//连接阿里云CentOS中Docker内的MySQL8.0
$conn2=mysqli_connect('116.62.155.140:3306','root','ma1bao2') or die("连接失败 ".mysqli_connect_error());
🍎
Warning: mysqli_connect(): The server requested authentication method unknown to the client [caching_sha2_password] in C:\fastwork\Apache24\htdocs\init-mysql.php on line 14
解决流程:
- 配置
mysql.cnf
配置默认身份验证插件
[mysqld]
default_authentication_plugin = mysql_native_password
SELECT Host, User, plugin from user;
mysql> SELECT Host, User, plugin from user;
+-----------+------------------+-----------------------+
| Host | User | plugin |
+-----------+------------------+-----------------------+
| % | root | caching_sha2_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | mysql_native_password |
+-----------+------------------+-----------------------+
还得改 % , % 表示外部用户连接
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
😭终于成功了…🍎
数据插入成功!阿里云数据插入成功!
61
1
🌴 连接服务器中Docker内的MySQL
连库基本操作
1.连接数据库服务器
资源 mysql_connect(服务器地址,用户名,密码)
php7改用 mysqli_connect 连接数据库;若仍旧使用 mysql_connect 则报错:
Fatal error: Uncaught Error: Call to undefined function mysql_connect() in C:\fastwork\Apache24\htdocs\test.php:7
Stack trace:
#0 {main}
thrown in C:\fastwork\Apache24\htdocs\test.php on line 7
PHP连接方式:
- 面向过程方式
header('Content-type:text/html;charset=utf-8');
echo '<pre>';
//主机地址:默认端口3306
$servername = "localhost";
$username = "root";
$password = "123456";
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
//或者采用短路运算方式(https://segmentfault.com/a/1190000002949450) 👇
//$conn=mysqli_connect('127.0.0.1:3306','roo2t','123456') or die("连接失败 ".mysqli_connect_error());
// 检测连接
if (!$conn) { //👉也可以 if (mysqli_connect_error())
die("连接失败: " ); mysqli_connect_error());
}
var_dump($conn);
//关闭连接
mysqli_close($conn);
🍎
object(mysqli)#1 (19) {
["affected_rows"]=>
int(0)
["client_info"]=>
string(79) "mysqlnd 5.0.12-dev - 20150407 - $Id: 7cc7cc96e675f6d72e5cf0f267f48e167c2abb23 $"
["client_version"]=>
int(50012)
["connect_errno"]=>
int(0)
["connect_error"]=>
NULL
["errno"]=>
int(0)
["error"]=>
string(0) ""
["error_list"]=>
array(0) {
}
["field_count"]=>
int(0)
["host_info"]=>
string(20) "localhost via TCP/IP"
["info"]=>
NULL
["insert_id"]=>
int(0)
["server_info"]=>
string(6) "8.0.17"
["server_version"]=>
int(80017)
["stat"]=>
string(135) "Uptime: 3074 Threads: 2 Questions: 120 Slow queries: 0 Opens: 306 Flush tables: 3 Open tables: 226 Queries per second avg: 0.039"
["sqlstate"]=>
string(5) "00000"
["protocol_version"]=>
int(10)
["thread_id"]=>
int(48)
["warning_count"]=>
int(0)
}
连接资源默认也是超全局的,任何地方都可以使用该资源进行数据库的其他操作
- 使用 PDO 连接 MySQL
try {
$conn = new PDO("mysql:host=$servername;", $username, $password);
echo "连接成功";
}
catch(PDOException $e)
{
echo "连接失败 ".$e->getMessage();
}
//关闭连接
$conn = null;
🍎失败情况
连接失败 SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
- 实际开发中 :
- 推荐使用 PDO连接方式 , 因为可以连接更多的数据库
- 使用函数 parse_ini_file() 解析配置文件 config.ini 来获得数据库连接参数 , 如下所示:
//解析config.ini文件
$config = parse_ini_file(realpath(dirname(__FILE__) . '/config/config.ini'));
//对mysqli类进行实例化
$conn = new mysqli($config['host'], $config['username'], $config['password'], $config['dbname']);
补充: mysql_connect 默认是对一个服务器只连接一次(如果再次运行,返回的是同一个资源),但是如果有需要连接同一个资源两次,那么可以使用第四个参数:TRUE
2.设置连接编码
保持客户端与服务器之间的沟通顺畅:同一“语言”(字符集)
//php7
mysqli_query($conn, "set character set 'utf8'");//读库
mysqli_query($conn,"set names 'utf8'");//写库
//php5
mysql_query("set character set 'utf8'");//读库
mysql_query("set names 'utf8'");//写库
🌰
//设定字符集
$res = mysqli_query($conn,"set names 'utf8'");//写库
//或者 $res = mysqli_set_charset($conn,'utf8');
var_dump($res);
🍎
bool(true)
怎么确定要使用何种编码 客户端当前执行脚本的界面是什么字符集,就设定成什么字符集
3.选定要使用的数据库
$res = mysqli_query($conn,'use examples');
//或者 $res = mysqli_select_db($conn,'examples');
var_dump($res);
🍎
bool(true)//表示连接数据库成功
4.关闭连接
$res = mysqli_close($conn);
var_dump($res);
执行增删改操作
- 环境准备:
create database News charset utf8;
create table n_news(
id int primary key auto_increment,
title varchar(50) not null comment '新闻标题',
isTop tinyint not null comment '是否置顶',
content text comment '内容',
publiser varchar(20) not null comment '发布人',
pub_time int not null comment '发布时间'
)charset utf8;
- 做个专门负责数据库初始化的脚本:之后要操作数据库包含该脚本即可
header('Content-type:text/html;charset=utf-8');
echo '<pre>';
//连接认证
$conn=mysqli_connect('127.0.0.1:3306','root','123456') or die("连接失败 ".mysqli_connect_error());
//设定字符集
mysqli_query($conn,'set names utf8');
//选择数据库
mysqli_query($conn,'use News');
insert 插入
//引入初始文件
include_once 'init-mysql.php';
//组织SQL指令
$pub_time = time();
$sql = "insert into n_news values(null,'11.PHP的MySQL扩展',1,'MySQL扩展......','Javakam',{$pub_time})";
//执行SQL指令
if(mysqli_query($conn,$sql)){
//操作成功:通常是返回自增长ID给用户
echo '数据插入成功!';
}else{
//操作失败
echo '数据插入失败!'.mysqli_error($conn);;
}
delete 删除
//组织SQL指令:实际删除时通常也是根据ID进行删除,但是ID都是传递过来
$sql = "delete from n_news where id = 5";
update 修改
//组织SQL指令:实际更新时通常也是根据ID进行更新,但是ID都是传递过来
$sql = "update n_news set content = '好嗨友' where id = 20";
判断执行结果
- 执行成功,结果为true,只代表SQL指令执行成功
- 执行失败,结果为false,代表SQL指令错误或者操作对象不存在
select
查询
mysql_query("select ...")
- 其他类似查询语句,比如:show语句,desc语句
以上两种情况的总结:凡是执行操作希望拿到数据库返回的数据进行展示的(结果返回:数据结果)
- 执行结果的处理:成功为结果集,失败为false
成功返回结果:SQL指令没有错误,但是如果查询结果本身为空返回也是true(结果集是一种资源:转换成bool永远为TRUE)
include_once 'init-mysql.php';
//组织SQL指令
$sql = "select * from n_news";
$res=mysqli_query($conn,$sql);
var_dump($res);
🍎
object(mysqli_result)#2 (5) {
["current_field"]=>
int(0)
["field_count"]=>
int(6)
["lengths"]=>
NULL
["num_rows"]=>
int(18)
["type"]=>
int(0)
}
获取结果集行数
mysqli_num_rows('查询结果集合')
:获取结果集中到底有多少行记录
include_once 'init-mysql.php';
//组织SQL指令
$sql = "select * from n_news";
$res=mysqli_query($conn,$sql);
//获取结果集数据条数:多少行记录
$rows = mysqli_num_rows($res);
echo $rows;
🍎
18
解析结果集
将一种结果集资源(PHP不能直接使用),转换成一种PHP能够解析的数据格式:通过从结果集中(结果集指针:类似数组指针),按照结果集指针所在位置取出对应的一条记录(一行),返回一个数组,同时指针下移…直到指针移出结果集。
- mysqli_fetch_assoc(): 获取关联数组,表的表单名字作为数组下标,元素值作为数组元素值
//解析结果集
$row = mysqli_fetch_assoc($res);
echo '<pre>';
print_r($row);
🍎
Array
(
[id] => 4
[title] => 11.PHP的MySQL扩展
[isTop] => 1
[content] => MySQL扩展......
[publiser] => Javakam
[pub_time] => 1571639075
)
- mysql_fetch_row(): 获取索引数组,只获取数据的值,然后数组的下标从0开始自动索
$row = mysqli_fetch_row($res);
🍎
Array
(
[0] => 4
[1] => 学校学习L扩展111
[2] => 1
[3] => MySQL扩展......
[4] => Javakam
[5] => 1571639075
)
- mysql_fetch_array():获取关联或者索引数组,但是默认是同时存在:一个记录取两次,形成一组是关联数组,一组是索引数组;
但是可以通过第二个参数来决定获取的方式:MYSQL_ASSOC只获取关联数组;MYSQL_NUM只获取索引数组;MYSQL_BOTH获取全部两种。
//MYSQL_FETCH_ARRAY
$row = mysqli_fetch_array($res);
print_r($row);
//获取两种
$row = mysqli_fetch_array($res,MYSQLI_BOTH);
print_r($row);
//获取关联
$row = mysqli_fetch_array($res,MYSQLI_ASSOC);
print_r($row);
//获取索引
$row = mysqli_fetch_array($res,MYSQLI_NUM);
print_r($row);
echo '<pre>';
print_r($row);
🍎
Array
(
[0] => 4
[id] => 4
[1] => 学校学习L扩展111
[title] => 学校学习L扩展111
[2] => 1
[isTop] => 1
[3] => MySQL扩展......
[content] => MySQL扩展......
[4] => Javakam
[publiser] => Javakam
[5] => 1571639075
[pub_time] => 1571639075
)
Array
(
[0] => 6
[id] => 6
[1] => 2312321的MySQL扩展
[title] => 2312321的MySQL扩展
[2] => 1
[isTop] => 1
[3] => MySQL扩展......
[content] => MySQL扩展......
[4] => Javakam
[publiser] => Javakam
[5] => 1571639079
[pub_time] => 1571639079
)
Array
(
[id] => 7
[title] => 11.PHP的MySQL扩展
[isTop] => 1
[content] => MySQL扩展......
[publiser] => Javakam
[pub_time] => 1571639496
)
Array
(
[0] => 8
[1] => 打撒撒多`的MySQL扩展
[2] => 1
[3] => MySQL扩展......
[4] => Javakam
[5] => 1571639497
)
Array
(
[0] => 8
[1] => 打撒撒多`的MySQL扩展
[2] => 1
[3] => MySQL扩展......
[4] => Javakam
[5] => 1571639497
)
1.2.3 三种方式,都会使指针下移,mysqli_fetch_array 的结果所示。
通常结果集的操作:一般是获取里面的所有(全部记录)
其他相关函数
有字段信息
- mysqli_num_fields():获取一个指定结果集中所有的字段数
//查询当前结果集中所有的字段数量 👉 table有几个字段
echo mysqli_num_fields($res);
🍎
6
- mysqli_fetch_field_direct():获取一个指定结果集中指定位置字段的名字 php7中已废弃 mysqli_field_name() 👉 https://dev.mysql.com/doc/apis-php/en/apis-php-function.mysql-field-name.html
//查询当前结果集中所有的字段数量 , 默认从索引0开始
print_r(mysqli_fetch_field_direct($res,1));
🍎
stdClass Object
(
[name] => title
[orgname] => title
[table] => n_news
[orgtable] => n_news
[def] =>
[db] => news
[catalog] => def
[max_length] => 27
[length] => 150
[charsetnr] => 33
[flags] => 4097
[type] => 253
[decimals] => 0
)
有关出错信息
- mysqli_error(‘数据库连接对象 $conn’):获取出错对应的提示信息
- mysqli_errno(‘数据库连接对象 $conn’):获取出错对应的错误提示代号
//错误判定
if(!$res){
//代表结果为false
echo 'SQL指令执行出错,错误编号为:' . mysqli_errno($conn) . '<br/>';
echo 'SQL指令执行出错,错误信息是:' . mysqli_error($conn) . '<br/>';
//终止代码执行
exit();
}
🍎
SQL指令执行出错,错误编号为:1064
SQL指令执行出错,错误信息是:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from2 n_news' at line 1
其他函数
mysql_insert_id($conn) : 获取上次插入操作所产生的自增长ID,如果没有自增长ID返回0
//引入初始文件
include_once 'init-mysql.php';
//组织SQL指令
$pub_time = time();
$sql = "insert into n_news values(null,'11.PHP的MySQL扩展',1,'MySQL扩展......','Javakam',{$pub_time})";
//执行SQL指令
$res=mysqli_query($conn,$sql);
if($res){
//操作成功:通常是返回自增长ID给用户
echo '数据插入成功!';
}else{
//代表结果为false
echo 'SQL指令执行出错,错误编号为:' . mysqli_errno($conn) . '<br/>';
echo 'SQL指令执行出错,错误信息是:' . mysqli_error($conn) . '<br/>';
//终止代码执行
exit();
}
//获取自增长ID
echo mysqli_insert_id($conn);
🍎 每刷新一次浏览器,自增1
数据插入成功!31