php操作数据库(mysql).
一、PHP数据库扩展分类.
- MySQL 扩展
- MySQLi 扩展
- PDO扩展
1.MySQL扩展.
MySQL 扩展是针对 MySQL 4.1.3 或更早版本设计的,是 PHP 与 MySQL数据库交互的早期扩展。由于其不支持 MySQL 数据库服务器的新特性,且安全性差,在项目开发中不建议使用,可用 MySQLi 扩展代替
2.MySQLi 扩展.
MySQLi 扩展是 MySQL 扩展的增强版,它不仅包含了所有 MySQL 扩展的功能函数,还可以使用 MySQL 新版本中的高级特性。
例如,多语句执行和事务的支持,预处理方式完全解决了 SQL 注入问题等。MySQLi 扩展只支持MySQL 数据库,如果不考虑其他数据库,该扩展是一个非常好的选择。
3.PDO 扩展.
PDO 是 PHP Data Objects(数据对象)的简称,它提供了一个统一的 API接口,只要修改其中的 DSN (数据源),就可以实现PHP应用与不同类型数据库服务器之间的交互。
PHP中的数据库扩展需要到php.ini中打开,然后重启服务
去掉 extension 前的 ;即可
extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_pdo_mysql.dll
二、PHP访问MySQL的基本步骤.
三、对比MySQL和MySQLi扩展.
MySQLi扩展 支持两种语法,①面向过程 ②面向对象
MySQL扩展用法 非常相似的面向过程语法,即使用函数完成 PHP 与 MySQL的交互
面向过程 函数
基本步骤 | MySQL扩展 | MySQLi扩展 |
---|---|---|
连接和选择数据库 | mysql_connect() | mysqli_connect() |
执行SQL语句 | mysql_query() | mysqli_query() |
处理结果集 | mysql_fetch_array() | mysqli_fetch_array() |
释放结果集 | mysql_free_result() | mysqli_free_result() |
关闭连接 | mysql_close() | mysqli_close() |
四、连接数据库(面向过程).
//函数
mysqli mysqli_connect (
string $host = ini_get('mysqli.default_host'), //主机名或 IP
string $username = ini_get('mysqli.default_user'), //用户名
string $passwd = ini_get('mysqli.default_pw'), //密码
string $dbname = '', //数据库名
int $port = ini_get('mysqli.default_port'), //端口号
string $socket = ini_get('mysqli.default_socket') //socket 通信
)
/*函数有 6 个可选参数,当省略时参数时,自动使用 php.ini 中配置的默认值。连接成功时,该函数返回数据库连接;连接失败时,函数返回 false,并提示 Warning 级错误信息。参数 $socket 表示socket 通信方式,通常不需要设置*/
(1) 连接并选择数据库.
//连接数据库,并通过$link保存连接
$link = mysqli_connect('localhost', 'root', 'root', 'phpdb','3307');
(2) 自定义错误信息.
当数据库连接失败时,mysqli_connect() 提示的错误信息并不友好,可以通过下面的方式解决。
//连接数据库,并屏蔽错误信息
$link = @mysqli_connect('localhost', 'root', 'root') or exit('数据库连接失败');
/*
“@”用于屏蔽函数的错误信息
“or”是比较运算符 只有左边表达式的值为 false 时,才会执行右边的表达式
“exit”用于停止脚本,同时可以输出错误信息
当需要详细的错误信息时,可以通过mysqli_connect_error() 函数来获取
*/
(3) 设置字符集.
//设置字符集
mysqli_set_charset($link, 'utf8'); //成功返回true,失败返回false
注意
只有保持 PHP 脚本文件、Web 服务器返回的编码、网页的 标记、PHP 访问 MySQL 使用的字符集都统一时,才能避免中文出现乱码问题
五、执行SQL语句(面向过程).
//函数
mixed mysqli_query (
mysqli $link, //数据库连接
string $query, //SQL语句
int $resultmode = MYSQLI_STORE_RESULT //结果集模式
)
注意
当函数执行 SELECT、SHOW、DESCRIBE 或EXPLAIN 查询时,返回值是查询结果集,而对于其他查询,成功返回 true,失败返回 false。
可选参数 $resultmode 的值:
① MYSQLI_STORE_RESULT:会将结果集全部读取到 PHP 端
② MYSQLI_USE_RESULT :仅初始化结果集检索,在处理结果集时进行数据读取
//连接数据库
$link = mysqli_connect('localhost', 'root', '123456');
mysqli_query($link, 'use `itcast`'); //选择数据库(SQL语句方式)
mysqli_query($link, 'set names utf8'); //设置字符集(SQL语句方式)
//执行SQL语句,并获取结果集
$result = mysqli_query($link, 'show databases');
if(!$result){
exit('执行失败。错误信息:'.mysqli_error($link));
}
六、处理结果集(面向过程).
当通过 mysqli_query() 函数执行 SQL 语句后,返回的结果集并不能直接使用,需要使用函数从结果集中获取信息,保存为数组
在表列举函数中,mysqli_fetch_all() 和 mysqli_fetch_array() 的返回值支持关联数组和索引数组两种形式,
函数第 1 个参数表示结果集,
第 2 个参数是可选参数,表示返回的数组形式,其值有 MYSQLI_ASSOC、MYSQLI_NUM、MYSQLI_BOTH 三种常量,分别表示关联数组、索引数组,或两者皆有,默认值为 MYSQLI_BOTH。
1.一次查询一行记录.
当需要一次查询一行记录时,可以通过 mysqli_fetch_assoc()、mysqli_fetch_row() 或 mysqli_fetch_array() 来实现
//通过循环将结果集中所有的记录全部读取
while($row = mysqli_fetch_assoc($result)){
echo $row['name']; //输出“name”字段的值
}
2. 一次查询所有记录.
当需要一次查询出所有的记录时,可以通过 mysqli_fetch_all() 函数来实现
//查询所有记录,获取关联数组结果
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
//打印数组结构
var_dump($data); //每行记录是一个数组,所有的行组成了$data数组
//MYSQLI_ASSOC,表示返回关联数组结果
//$data是一个包含所有行的二维数组,当访问第1行记录中的“name”时,可以通过“$data[0]['name']”进行访问
//使用 var_dump() 函数可以查看该数组的结构。
七、预处理语句(面向过程).
MySQLi 扩展中有一种预处理语句的机制,其原理是预先编译 SQL 语句的模板,当执行时只传输有变化的数据。下图演示了预处理语句和传统方式的区别。
从图中可以看出,当 PHP 需要执行 SQL 时,传统方式是将发送的数据和 SQL 写在一起,这种方式每条 SQL 都需要经过分析、编译和优化的周期;而预处理语句只需要编译一次用户提交的 SQL 模板,在操作时,发送相关数据即可完成更新操作,这极大地提高了运行效率,而且无需考虑数据中包含特殊字符(如单引号)导致的语法问题。
预处理相关函数
1.mysqli_prepare.
//用于预处理一个待执行的 SQL 语句
mysqli_stmt mysqli_prepare ( mysqli $link , string $query )
//参数 $link 表示数据库连接,$query 表示 SQL 语句模板。当函数执行后,成功返回预处理对象,失败返回 false
2.mysqli_stmt_bind_param.
//用于将变量作为参数绑定到预处理语句中
bool mysqli_stmt_bind_param (
mysqli_stmt $stmt, //预处理对象
string $types, //数据类型
mixed &$var1, //绑定变量1(引用传参)
[, mixed&$... ] //绑定变量n...(可选参数,可绑定多个,引用传参)
)
//数 $stmt 表示由 mysqli_prepare() 返回的预处理对象;$types 用于指定被绑定变量的数据类型,它是由一个或多个字符组成的字符串;后面的 $var(可以是多个参数)表示需要绑定的变量,且其个数必须与 $types 字符串的长度一致。该函数执行成功时返回 true,失败时返回 false
参数绑定时的数据类型字符
字符 | 描述 |
---|---|
i | 描述变量的数据类型为MySQL中的integer类型 |
d | 描述变量的数据类型为MySQL中的double类型 |
s | 描述变量的数据类型为MySQL中的string类型 |
b | 描述变量的数据类型为MySQL中的blob类型 |
//演示
//连接数据库、预处理SQL模板
$link = mysqli_connect('localhost', 'root', '123456', 'itcast');
$stmt = mysqli_prepare($link, 'UPDATE `user` SET `name`=? WHERE `id`=?');
//参数绑定(将变量$name、$id按顺序绑定到SQL语句“?”占位符上)
mysqli_stmt_bind_param($stmt, 'si', $name, $id);
3.mysqli_stmt_execute.
//在完成参数绑定后,接下来应该将数据内容发送给 MySQL 执行
bool mysqli_stmt_execute ( mysqli_stmt $stmt )
//$stmt 参数表示由 mysqli_prepare() 函数返回的预处理对象。当函数执行成功后,返回 true,执行失败返回 false。
//演示
//连接数据库、预处理SQL模板
$link = mysqli_connect('localhost', 'root', '123456', 'itcast');
$stmt = mysqli_prepare($link, 'UPDATE `user` SET `name`=? WHERE `id`=?');
//参数绑定,并为已经绑定的变量赋值
mysqli_stmt_bind_param($stmt, 'si', $name, $id);
$name = 'aa';
$id = 1;
//执行预处理(第一次执行)
mysqli_stmt_execute($stmt);
//为第二次执行重新赋值
$name = 'bb';
$id = 2;
//执行预处理(第二次执行)
mysqli_stmt_execute($stmt);
其他操作.
函数 | 描述 |
---|---|
mysqli_insert_id() | 获取上一次插入操作时产生的ID号 |
mysqli_affected_rows() | 获取上一次操作时受影响的行数 |
mysqli_real_escape_string() | 用于转义SQL语句字符串中的特殊字符 |
mysqli_free_result() | 释放结果集 |
mysqli_close() | 关闭先前打开的数据库连接 |
mysqli_error() | 返回最近函数调用的错误代码 |
mysqli_free_result() 和 mysqli_close() 函数用于释放资源、关闭连接,由于 PHP 访问 MySQL 使用了非持久连接,因此当 PHP 脚本执行结束时会自动释放。
完整操作(面向过程).
//连接数据库、设置字符集
$link = mysqli_connect('localhost', 'root', '123456', 'itcast');
mysqli_set_charset($link, 'utf8');
// ① 执行查询操作、处理结果集
if(!$result = mysqli_query($link, 'SELECT * FROM `user`')){
exit('执行失败。错误信息:'.mysqli_error($link)); //获取错误信息
}
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
// ② 用完后,释放结果集
mysqli_free_result($result);
// ③ 执行插入操作,拼接SQL语句
//转义特殊符号
$name = mysqli_real_escape_string($link, "单引号'测试'文本");
if(!mysqli_query($link, "INSERT INTO `user` (`name`) VALUES
('".$name."')")){
exit('执行失败。错误信息:'.mysqli_error($link));
}
// ④ 获取最后插入的ID
$id = mysqli_insert_id($link); //获取AUTO_INCREMENT字段的自增值
// ⑤ 执行修改操作
if(!mysqli_query($link, "UPDATE `user` SET `name`='aa' WHERE
`id`>2")){
exit('执行失败。错误信息:'.mysqli_error($link));
}
// ⑥ 获取受影响的行数
$num = mysqli_affected_rows($link); //可获取UPDATE、 //DELETE等操作影响的行数
// ⑦ 关闭连接
mysqli_close($link);
在上述代码中,第 4
10 行演示了 mysqli_error()、mysqli_free_result()函数的使用,第 12 行演示了 mysqli_real_escape_string() 函数的使用,第1725行演示了 mysqli_insert_id()、mysqli_affected_rows()、mysqli_close()函数的使用。其中第 8 行 $data 保存了查询出的数据,因此在第 10 行释放了$result 结果集。第 25 行关闭 $link 连接后,$link 将不能继续使用。