跳转到内容

PHP MySQLi扩展

来自代码酷
Admin留言 | 贡献2025年5月2日 (五) 00:28的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

PHP MySQLi扩展[编辑 | 编辑源代码]

PHP MySQLi扩展(MySQL Improved Extension)是PHP用于与MySQL数据库交互的增强接口,提供面向对象和面向过程两种编程方式。相比旧的mysql_*函数,MySQLi支持预处理语句、事务处理、多语句查询等现代数据库操作特性,是PHP开发者连接MySQL数据库的推荐方式之一。

概述[编辑 | 编辑源代码]

MySQLi扩展在PHP 5.0版本引入,主要改进包括:

  • 支持面向对象和面向过程两种API风格
  • 预处理语句(防止SQL注入)
  • 事务控制(ACID兼容)
  • 多查询执行
  • 服务器状态检查
  • 增强的调试能力

安装与配置[编辑 | 编辑源代码]

MySQLi通常随PHP默认安装,可通过以下命令检查是否启用:

<?php
phpinfo(); // 查找mysqli模块
?>

若未安装,需在php.ini中取消注释:

extension=mysqli

基础用法[编辑 | 编辑源代码]

连接数据库[编辑 | 编辑源代码]

面向对象风格

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");

// 检查连接
if ($mysqli->connect_error) {
    die("连接失败: " . $mysqli->connect_error);
}
echo "连接成功";
?>

面向过程风格

<?php
$conn = mysqli_connect("localhost", "username", "password", "database");

if (!$conn) {
    die("连接失败: " . mysqli_connect_error());
}
echo "连接成功";
?>

执行查询[编辑 | 编辑源代码]

查询示例

<?php
$sql = "SELECT id, name FROM users";
$result = $mysqli->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "ID: " . $row["id"]. " - Name: " . $row["name"]. "<br>";
    }
} else {
    echo "0 结果";
}
?>

预处理语句[编辑 | 编辑源代码]

预处理是防止SQL注入的最佳实践:

<?php
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);

// 设置参数并执行
$name = "John";
$email = "john@example.com";
$stmt->execute();

echo "新记录插入成功";
$stmt->close();
?>

参数类型说明:

  • i - 整数
  • d - 双精度浮点数
  • s - 字符串
  • b - 二进制数据

事务处理[编辑 | 编辑源代码]

MySQLi支持数据库事务:

<?php
$mysqli->autocommit(FALSE);

try {
    $mysqli->query("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");
    $mysqli->query("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2");
    
    $mysqli->commit();
    echo "转账成功";
} catch (Exception $e) {
    $mysqli->rollback();
    echo "事务失败: " . $e->getMessage();
}
?>

错误处理[编辑 | 编辑源代码]

推荐的错误处理方式:

<?php
// 面向对象
if ($mysqli->errno) {
    echo "错误代码: " . $mysqli->errno . "<br>";
    echo "错误信息: " . $mysqli->error;
}

// 面向过程
if (mysqli_errno($conn)) {
    echo "错误代码: " . mysqli_errno($conn) . "<br>";
    echo "错误信息: " . mysqli_error($conn);
}
?>

性能优化[编辑 | 编辑源代码]

多查询[编辑 | 编辑源代码]

MySQLi支持多查询执行(但需谨慎使用):

<?php
$sql = "
    SELECT * FROM users;
    SELECT * FROM products;
";

if ($mysqli->multi_query($sql)) {
    do {
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_row()) {
                print_r($row);
            }
            $result->free();
        }
    } while ($mysqli->more_results() && $mysqli->next_result());
}
?>

结果缓冲[编辑 | 编辑源代码]

使用缓冲查询提高性能:

<?php
// 默认缓冲查询
$result = $mysqli->query("SELECT * FROM large_table");

// 无缓冲查询(节省内存)
$result = $mysqli->query("SELECT * FROM very_large_table", MYSQLI_USE_RESULT);
?>

实际案例[编辑 | 编辑源代码]

用户注册系统[编辑 | 编辑源代码]

完整示例展示用户注册流程:

<?php
class UserRegistration {
    private $mysqli;
    
    public function __construct($mysqli) {
        $this->mysqli = $mysqli;
    }
    
    public function register($username, $password, $email) {
        // 检查用户名是否存在
        $stmt = $this->mysqli->prepare("SELECT id FROM users WHERE username = ?");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        
        if ($stmt->num_rows > 0) {
            throw new Exception("用户名已存在");
        }
        $stmt->close();
        
        // 插入新用户
        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
        $stmt = $this->mysqli->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
        $stmt->bind_param("sss", $username, $hashedPassword, $email);
        
        if (!$stmt->execute()) {
            throw new Exception("注册失败: " . $stmt->error);
        }
        
        return $stmt->insert_id;
    }
}

// 使用示例
$db = new mysqli("localhost", "user", "pass", "app_db");
$registration = new UserRegistration($db);

try {
    $userId = $registration->register("newuser", "secure123", "new@example.com");
    echo "注册成功,用户ID: " . $userId;
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>

与PDO的比较[编辑 | 编辑源代码]

特性 MySQLi PDO
数据库支持 仅MySQL 多种数据库
预处理语句 支持 支持
命名参数 不支持 支持
对象映射 有限支持 完整ORM支持
错误处理 多种模式 异常为主

最佳实践[编辑 | 编辑源代码]

1. 始终使用预处理语句防止SQL注入 2. 合理使用事务保证数据一致性 3. 关闭自动提交(autocommit(FALSE)) 4. 及时释放查询结果(free()/close()) 5. 使用适当的错误处理机制 6. 生产环境关闭错误显示(display_errors=Off)

常见问题[编辑 | 编辑源代码]

Q: 何时选择MySQLi而非PDO?
A: 当项目仅使用MySQL且需要MySQL特有功能时(如多查询、异步查询)。

Q: 如何获取最后插入的ID?
A: 使用$mysqli->insert_id属性(面向对象)或mysqli_insert_id($conn)函数(面向过程)。

Q: 为什么预处理语句更安全?
A: 因为参数与SQL指令分离,防止恶意SQL代码被执行。

进阶主题[编辑 | 编辑源代码]

存储过程调用[编辑 | 编辑源代码]

<?php
$stmt = $mysqli->prepare("CALL get_user_by_id(?)");
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
?>

元数据查询[编辑 | 编辑源代码]

获取表结构信息:

<?php
$result = $mysqli->query("SHOW COLUMNS FROM users");
while ($row = $result->fetch_assoc()) {
    print_r($row);
}
?>

总结[编辑 | 编辑源代码]

MySQLi扩展为PHP开发者提供了强大而灵活的MySQL数据库操作接口。通过结合预处理语句、事务控制和面向对象编程,可以构建安全高效的数据库应用。对于纯MySQL项目,MySQLi通常是比PDO更轻量且功能完整的选择。