必须显式指定charset,仅mysqli_connect()连接成功但未设utf8mb4会导致emoji插入失败;需立即调用mysqli_set_charset($conn, 'utf8mb4')或在dsn中添加charset=utf8mb4。

mysqli_connect() 连接 MySQL 时 charset 参数必须显式指定
PHP 8.0 默认不再隐式设置 utf8mb4,如果只写 mysqli_connect($host, $user, $pass, $db),连接虽成功,但后续插入 emoji 或四字节 UTF-8 字符会报错或截断。必须在连接后立即调用 mysqli_set_charset($conn, 'utf8mb4'),或改用 DSN 风格的面向对象初始化:
$conn = new mysqli($host, $user, $pass, $db, $port, $socket); $conn->set_charset('utf8mb4');- 若用过程式,
mysqli_connect()返回资源后立刻跟mysqli_set_charset($conn, 'utf8mb4'),不能省略 - 不设 charset 时,
SHOW VARIABLES LIKE 'character_set%'会显示latin1,不是你期望的
PDO 构造 DSN 时 MySQL 和 PostgreSQL 的协议名不能互换
写错 DSN 协议名是 PHP 8.0 下最常见连接失败原因,PDO 不报语法错误,而是直接抛出 PDOException: could not find driver。MySQL 必须用 mysql:,PostgreSQL 必须用 pgsql: —— 写成 postgres:、postgresql: 或漏掉冒号后的空格都会失败。
- MySQL 正确:
mysql:host=localhost;dbname=test;charset=utf8mb4 - PostgreSQL 正确:
pgsql:host=localhost;port=5432;dbname=test;user=pguser;password=pgpass - 错误示例:
postgres:host=...(驱动未注册)、pgsql: host=...(空格导致解析失败)
pg_connect() 在 PHP 8.0 中仍可用,但默认不启用 pgsql 扩展
即使代码里写了 pg_connect(),运行时大概率遇到 Fatal error: Uncaught Error: Call to undefined function pg_connect()。这不是函数被移除,而是 pgsql 扩展默认未加载 —— 和 mysqli 不同,它不随 PHP 二进制包自动启用。
- Linux:检查
php.ini是否有extension=pgsql,且未被分号注释;确认extension_dir指向正确路径(如/usr/lib/php/20200930/) - macOS(Homebrew):运行
brew install php@8.0-pgsql后重启 Web 服务 - Windows:取消
php.ini中;extension=php_pgsql.dll的分号,并确保 DLL 文件存在 - 验证命令:
php -m | grep pgsql或var_dump(extension_loaded('pgsql'));
持久连接在 PDO 中需手动开启,且 PostgreSQL 和 MySQL 行为不同
PHP 8.0 的 PDO 默认关闭持久连接,PDO::ATTR_PERSISTENT => true 必须显式传入选项数组。但注意:MySQL 的持久连接复用较稳定;PostgreSQL 的持久连接在长连接空闲超时后可能残留 server closed the connection unexpectedly 错误,尤其在 Nginx + PHP-FPM 场景下。
- MySQL 安全启用:
new PDO($dsn, $user, $pass, [PDO::ATTR_PERSISTENT => true]) - PostgreSQL 建议配合重试逻辑,例如捕获
PDOException中含server closed的消息后重新连接 - 不要在 CLI 脚本中滥用持久连接,PHP-FPM worker 生命周期内复用才有效,CLI 每次执行都是新进程
php -m 和 var_dump(PDO::getAvailableDrivers()),比反复改连接字符串更省时间。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











