php怎样连接mysql数据库_php连接mysql数据库常用办法【基础】

PHP 7.0+ 必须用 mysqli 或 PDO 连接 MySQL;mysqli_connect() 需判错并设 utf8mb4 字符集,PDO 需开启异常模式与正确 DSN;连接失败多因环境/权限问题,字符集和错误模式易被忽略却致乱码或静默失败。

mysqli_connect() 建立基础连接

PHP 7.0+ 已彻底移除 mysql_* 系列函数,必须改用 mysqliPDO。最直接的方式是调用 mysqli_connect(),它返回一个连接资源或 false

常见错误:连不上却没报错——因为默认关闭了错误提示。务必在连接后加判断:

if (!$conn = mysqli_connect('localhost', 'user', 'pass', 'db_name', 3306)) {
    die('连接失败:' . mysqli_connect_error());
}
  • 第 5 个参数(端口)可省略,默认 3306;但若 MySQL 运行在非标端口(如 Docker 映射为 3307),必须显式传入 3307
  • 连接成功后建议立即设置字符集,避免中文乱码:mysqli_set_charset($conn, 'utf8mb4')
  • 不要把密码硬编码在代码里,尤其上线后;应从环境变量或配置文件读取

PDO 实现更安全、可移植的连接

PDO 是面向对象方式,支持预处理语句、异常模式、多数据库切换,更适合现代项目。连接失败时默认静默,需手动开启异常模式:

$dsn = 'mysql:host=localhost;dbname=db_name;charset=utf8mb4';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
    $pdo = new PDO($dsn, 'user', 'pass', $options);
} catch (PDOException $e) {
    die('PDO 连接失败:' . $e->getMessage());
}
  • charset=utf8mb4 必须写在 $dsn 里,仅靠 setCharset() 不保证连接初始化阶段的字符集正确
  • PDO

    ::ATTR_ERRMODE
    设为 EXCEPTION 才能捕获连接/查询错误;默认是 SILENT,出错只返回 false
  • 若使用 Unix socket(如 MAMP、某些云服务),$dsn 应写成:mysql:unix_socket=/tmp/mysql.sock;dbname=db_name

连接失败的典型现象和排查点

不是代码写错,而是环境或权限问题导致连接中断,这类错误往往不报具体原因:

  • 报错 Connection refused:MySQL 服务未运行,或 bind-address 配置为 127.0.0.1 却尝试用 localhost 连(注意:PHP 中 localhost 会走 socket,而 127.0.0.1 走 TCP)
  • 报错 Access denied for user:用户名密码错、用户无远程访问权限(检查 GRANT 是否含 @'%' 或对应 IP)、或 MySQL 8 默认认证插件是 caching_sha2_password,旧版 PHP 不兼容(需改用 mysql_native_password
  • 超时无响应:防火墙拦截、云服务器安全组未放行 3306、或连接池耗尽(尤其短连接高频请求时)

别忽略连接生命周期管理

PHP 脚本结束时连接自动释放,但显式关闭更可控,尤其在长脚本或 CLI 场景下:

  • mysqli:用 mysqli_close($conn);不关也不会泄漏,但高并发下可能提前触达连接数上限
  • PDO:设 $pdo = null 或让对象超出作用域即可;调用 $pdo = null 后再访问会报致命错误,适合强制清理
  • 如果用连接池(如 Swoole、RoadRunner),不能依赖脚本结束自动释放,必须手动 close() 或归还到池中

真正容易被忽略的是字符集和错误模式——它们不报错,但会让后续查询结果错位、乱码或静默失败,调试成本远高于写两行初始化代码。