




面向对象方式应使用 new mysqli() 实例化连接,而非 mysqli_connect();连接后立即调用 set_charset('utf8mb4');预处理需 prepare()+bind_param();事务需 begin_transaction()/commit();每次请求新建连接。
用 mysqli 做面向对象连接,不是调用函数 mysqli_connect(),而是实例化 mysqli 类。这个类构造函数本身就能完成连接,失败时抛出警告或返回 false(取决于是否开启异常模式)。
常见错误是混用过程式写法:mysqli_connect(...) 后又试图调用 $conn->query(...) —— 这会报 Fatal error: Call to a member function query() on boolean,因为 mysqli_connect() 返回的是资源或 false,不是对象。
$mysqli = new mysqli($host, $user, $pass, $db, $port, $socket)
$mysqli->connect_error 有具体错误信息,$mysqli->connect_errno 是错误码mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
即使你在 new mysqli() 时传了 $charset 参数(第 6 个),它只影响客户端通知服务器“我打算用这个编码”,不保

Incorrect string value 错误。
$mysqli->set_charset('utf8mb4')
SET NAMES utf8mb4 查询代替 —— 它不如 set_charset() 可靠,尤其在预处理语句场景下utf8mb4 是必须的,utf8 在 MySQL 中只是 utf8mb3 的别名,不支持 emoji 和部分生僻汉字prepare() + bind_param() 配合面向对象方式下,不能像过程式那样用 mysqli_prepare() 函数。所有操作都走对象方法链,且类型绑定不能省略。
典型错误是拼接变量进 SQL 字符串,或者忘记 bind_param() 就直接 execute(),结果查不到数据、插入空值,甚至触发 Number of variables doesn’t match number of parameters in prepared statement。
?,不要用命名参数(MySQLi 不支持 :name)bind_param() 第一个参数是类型字符串:'s'(string)、'i'(int)、'd'(double)、'b'(blob);多个参数连写,如 'si'
bind_param('s', $name) 而不是 bind_param('s', $name)(PHP 7.4+ 允许值传递,但低版本仍需 &$name)begin_transaction() 和 commit()
MySQLi 面向对象不支持自动事务。即使你开了 AUTOCOMMIT=0,也得靠代码驱动。漏掉 commit() 或 rollback(),会导致连接关闭时自动回滚,你以为成功了,其实没持久化。
$mysqli->begin_transaction()(PHP 5.5+),比 $mysqli->query('START TRANSACTION') 更清晰$mysqli->commit();失败时用 $mysqli->rollback()
SELECT 不会锁表,除非加 FOR UPDATE 或 LOCK IN SHARE MODE
最容易被忽略的是连接复用和长连接管理:MySQLi 对象不是线程安全的,也不能跨请求复用;每次 HTTP 请求应新建对象,用完不需显式 close()(脚本结束自动释放),但高并发下建议主动 $mysqli->close() 避免连接数打满。