CodeIgniter 4 官方推荐 PDO,因其统一驱动接口、支持命名参数、事务更稳且可控制预处理;配置需严格匹配 DSN 格式与扩展启用,否则易报错。

MySQLi 和 PDO 选哪个?
CodeIgniter 3 默认用 mysqli,4.x 开始官方推荐 PDO。不是因为 PDO 更快,而是它统一了驱动接口,切换数据库(比如从 MySQL 换到 PostgreSQL)时,只需改 DSN 和 driver,不用动模型里的 SQL 写法。
-
mysqli 更轻量,对纯 MySQL 场景够用,但不支持命名参数(:name),预处理只能用问号占位
-
PDO 支持命名参数、事务嵌套更稳、能通过 PDO::ATTR_EMULATE_PREPARES 控制是否模拟预处理——关掉它才能真正利用 MySQL 的 prepare 缓存
- CodeIgniter 4 的
Database 类底层全走 PDO,即使你配 mysqli,也会被自动转成 PDO 封装,实际没差别
配置文件里 driver 和 DSN 怎么配才不报错?
常见错误是只改了 driver 却漏掉 DSN,或者 DSN 格式不对。CI 4 要求:如果设 driver => 'pdo',就必须填 DSN;而 mysqli 可以不写 DSN,靠 host/username 等字段拼。
-
mysqli 配置示例:
'DSN' => '',
'driver' => 'mysqli',
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'app_db'
-
PDO 必须带 DSN,格式为 mysql:host=localhost;dbname=app_db;charset=utf8mb4,注意:
-
charset 要显式写,否则可能存入乱码(尤其含 emoji)
- 不要加
port 参数在 DSN 里,CI 会忽略它;端口应单独写 'port' => 3307
-
unix_socket 路径不能写在 DSN 里,得用 'socket' => '/var/run/mysqld/mysqld.sock'
“Call to undefined function mysqli_init()” 是什么情况?
这是 PHP 缺少 mysqli 扩展,不是 CodeIgniter 配错了。CI 3 启动时会检测扩展是否存在,但有些 Docker 镜像或精简版 PHP 默认不装。
- 运行
php -m | grep mysqli 确认扩展已启用
- Ubuntu/Debian 下装:
sudo apt install php-mysqli
- Alpine(Docker 常用):
apk add php7-mysqli(注意版本号)
- 如果用的是
PDO 驱动,这个错误其实不该出现——但 CI 3 在初始化时仍会尝试加载 mysqli 类(兼容逻辑),所以哪怕你配的是 PDO,没装 mysqli 扩展也会挂掉
CI 4 中 database.php 里为什么没有 driver 字段?
CI 4 把驱动选择移到了 .env 文件,靠 database.default.driver 控制,app/Config/Database.php 里只负责读取环境变量并组装配置。
-
.env 中写:database.default.driver = "MySQLi"
# 或
database.default.driver = "PDO"
- 注意大小写:
MySQLi 不是 mysqli,CI 4 的驱动类名是 PascalCase
- 如果 .env 里没设,CI 4 会 fallback 到
MySQLi,但不会报错——容易误以为配成功了,其实连的不是你想要的驱动
mysqli 更轻量,对纯 MySQL 场景够用,但不支持命名参数(:name),预处理只能用问号占位PDO 支持命名参数、事务嵌套更稳、能通过 PDO::ATTR_EMULATE_PREPARES 控制是否模拟预处理——关掉它才能真正利用 MySQL 的 prepare 缓存Database 类底层全走 PDO,即使你配 mysqli,也会被自动转成 PDO 封装,实际没差别driver 却漏掉 DSN,或者 DSN 格式不对。CI 4 要求:如果设 driver => 'pdo',就必须填 DSN;而 mysqli 可以不写 DSN,靠 host/username 等字段拼。
-
mysqli配置示例:'DSN' => '', 'driver' => 'mysqli', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', 'database' => 'app_db'
-
PDO必须带 DSN,格式为mysql:host=localhost;dbname=app_db;charset=utf8mb4,注意:-
charset要显式写,否则可能存入乱码(尤其含 emoji) - 不要加
port参数在 DSN 里,CI 会忽略它;端口应单独写'port' => 3307 -
unix_socket路径不能写在 DSN 里,得用'socket' => '/var/run/mysqld/mysqld.sock'
-
“Call to undefined function mysqli_init()” 是什么情况?
这是 PHP 缺少 mysqli 扩展,不是 CodeIgniter 配错了。CI 3 启动时会检测扩展是否存在,但有些 Docker 镜像或精简版 PHP 默认不装。
- 运行
php -m | grep mysqli 确认扩展已启用
- Ubuntu/Debian 下装:
sudo apt install php-mysqli
- Alpine(Docker 常用):
apk add php7-mysqli(注意版本号)
- 如果用的是
PDO 驱动,这个错误其实不该出现——但 CI 3 在初始化时仍会尝试加载 mysqli 类(兼容逻辑),所以哪怕你配的是 PDO,没装 mysqli 扩展也会挂掉
CI 4 中 database.php 里为什么没有 driver 字段?
CI 4 把驱动选择移到了 .env 文件,靠 database.default.driver 控制,app/Config/Database.php 里只负责读取环境变量并组装配置。
-
.env 中写:database.default.driver = "MySQLi"
# 或
database.default.driver = "PDO"
- 注意大小写:
MySQLi 不是 mysqli,CI 4 的驱动类名是 PascalCase
- 如果 .env 里没设,CI 4 会 fallback 到
MySQLi,但不会报错——容易误以为配成功了,其实连的不是你想要的驱动
php -m | grep mysqli 确认扩展已启用sudo apt install php-mysqli
apk add php7-mysqli(注意版本号)PDO 驱动,这个错误其实不该出现——但 CI 3 在初始化时仍会尝试加载 mysqli 类(兼容逻辑),所以哪怕你配的是 PDO,没装 mysqli 扩展也会挂掉.env 文件,靠 database.default.driver 控制,app/Config/Database.php 里只负责读取环境变量并组装配置。
-
.env中写:database.default.driver = "MySQLi" # 或 database.default.driver = "PDO"
- 注意大小写:
MySQLi不是mysqli,CI 4 的驱动类名是 PascalCase - 如果 .env 里没设,CI 4 会 fallback 到
MySQLi,但不会报错——容易误以为配成功了,其实连的不是你想要的驱动
配置驱动这事,表面只是改个字符串,背后牵着扩展加载、字符集、预处理行为、甚至 Docker 容器里的 PHP 模块安装。最容易被跳过的,其实是确认 PHP 实际加载了哪个扩展,而不是光看 CI 的配置文件写了什么。











