codeigniter数据库配置中port必须显式声明为整数,非默认端口(如3307)不可省略,否则将回退至驱动默认值3306导致连接失败;需在对应环境的database.php中完整定义,且注意socket连接时应使用127.0.0.1而非localhost。

database.php 里必须显式写 port 配置项
CodeIgniter 不会自动推导非默认端口,哪怕你用的是 MySQL 5.7 或 MariaDB —— 只要不是 3306,port 就不能省。CI3 的数据库驱动(如 mysqli、pdo_mysql、postgre)都依赖这个字段走 TCP 连接,漏掉就会 fallback 到驱动内置默认值(通常是 3306),导致连错实例或直连失败。
配置位置在 application/config/database.php 的对应数据库组里,比如:
$db['default']['hostname'] = '127.0.0.1'; $db['default']['username'] = 'root'; $db['default']['password'] = 'pass'; $db['default']['database'] = 'myapp'; $db['default']['dbdriver'] = 'mysqli'; $db['default']['port'] = 3307; // ← 必须是整数,不能加引号
-
port值必须为纯数字(如3307),写成字符串'3307'在部分 CI3 版本中会被忽略 - PostgreSQL 用户注意:
postgre驱动同样需要port,且默认是5432;改用5433时也得显式填 - 如果用了 socket 连接(
hostname是localhost),port会被完全忽略——此时应改用127.0.0.1并配port
连不上时先验证端口是否真在监听
配置写了不等于服务在跑。常见情况是:MySQL 实例绑定了 127.0.0.1:3307,但你本地用 mysql -h localhost -P 3307 死活连不上——因为 localhost 触发了 socket 模式,压根没走 TCP。
快速验证方式:
- 终端执行:
netstat -tuln | grep :3307(Linux/macOS)或netstat -ano | findstr :3307(Windows),确认端口处于LISTEN状态 - 用
mysql -h 127.0.0.1 -P 3307 -u root -p测试 CLI 是否能通(强制走 TCP) - CI 报错
Unable to connect to your database server且db_debug = TRUE时,错误信息末尾通常带具体 errno,如(HY000/2003)表示连接被拒,大概率是端口不通或防火墙拦截
多环境配置下 port 容易被覆盖
如果你按环境拆了配置(比如 application/config/production/database.php),记得每个环境文件里都要单独设 port。CI 加载逻辑是「覆盖式合并」,父级 database.php 里的 port 不会自动继承到子环境。
典型错误写法:
// application/config/database.php $db['default']['port'] = 3306; // application/config/production/database.php $db['default']['hostname'] = 'prod-db.example.com'; // ← 这里没写 port,结果还是用了 3306
正确做法是每个环境配置文件中完整声明所有关键字段,包括 port:
$db['default']['port'] = 3308; // 生产库专用端口
- Docker 场景下尤其要注意:容器内 MySQL 的端口映射(如
-p 3308:3306)对外暴露的是3308,但容器内服务实际监听3306;CI 运行在容器外时,port应填映射后的宿主机端口(3308) - CI4 用户注意:
app/Config/Database.php中的port字段名已改为port(保持一致),但必须写在$default数组内,不能丢在全局作用域
使用 $this->load->database() 时端口不生效?检查加载时机
端口配置只在数据库类初始化时读取一次。如果你在控制器里手动调用 $this->load->database() 却发现连的是默认 3306,很可能是:
- 没传入正确的 group 名(比如写了
$this->load->database('prod'),但配置里定义的是$db['production']) - 在
__construct()里加载了default组,后面又想切到其他组但没加TRUE参数,导致新实例没赋给变量:$second_db = $this->load->database('second', TRUE);—— 缺TRUE就不会返回实例,port配置自然不生效 -
database.php被 APCu / OPcache 缓存,改完没清缓存,PHP 还在用旧配置(CLI 下可运行php -r "opcache_reset();"快速验证)
端口这种底层连接参数,一旦配错,错误发生在框架最外层,调试代码根本跑不到。盯住 port 类型、位置、环境隔离和加载方式这四点,基本就能排除 90% 的“连不上”问题。











