PHP MySQL 连接

Establishing a PDO connection, exception handling, and correct parameters.

Beginner
Key PointsKeep credentials in config, never hardcoded; always enable `ERRMODE_EXCEPTION`.

Connecting

PHP
<?php
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=demo;charset=utf8mb4";

try {
    $pdo = new PDO($dsn, "root", "secret", [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ]);
} catch (PDOException $e) {
    http_response_code(500);
    error_log("数据库连接失败: " . $e->getMessage());
    exit("服务暂时不可用");
}

echo "连接成功\n";
$n = (int)$pdo->query("SELECT 1")->fetchColumn();
echo $n === 1 ? "查询正常" : "查询异常", "\n";
Output
连接成功
查询正常
**Never echo $e->getMessage()** — it can include host, user and even password. Log it, show a generic message.

Using a config file

PHP
<?php
// config.php 内容:<?php return ["dsn" => "...", "user" => "...", "pass" => "..."];
$conf = require __DIR__ . "/config.php";

$pdo = new PDO($conf["dsn"], $conf["user"], $conf["pass"], [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

echo "已连接: " . $conf["dsn"], "\n";
Output
已连接: mysql:host=127.0.0.1;dbname=demo;charset=utf8mb4

Better still, read from environment variables via getenv("DB_PASSWORD"). Keep config out of Git and inject secrets in the container.

Common connection failures

ErrorCauseFix
could not find driver没装 pdo_mysql装扩展并重启 PHP-FPM
Connection refusedMySQL 没启动或端口不通查服务状态、防火墙
Access denied用户名密码错或主机无权限检查授权与 host 字段
Unknown database库名写错或没建先 CREATE DATABASE
Too many connections连接没释放,或并发过高短连接用完即弃,或上连接池
Cannot connect to 127.0.0.1localhost 走了 socket 而不是 TCP用 127.0.0.1 强制 TCP
With host=localhost the client tries a Unix socket and fails if the path is wrong. **Use 127.0.0.1 to force TCP** and rule out a whole class of issues.

Persistent connections

PHP
<?php
// 持久连接:请求结束后不真正关闭,复用给下一个请求
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_PERSISTENT => true,
    PDO::ATTR_ERRMODE    => PDO::ERRMODE_EXCEPTION,
]);

echo "持久连接已开启\n";
Output
持久连接已开启
Persistent connections save handshakes but leak transaction state and temp tables across requests. An uncommitted transaction keeps holding locks. Commit or roll back explicitly every request.

Closing

PHP releases it at script end. To release early, set the variable to null; PDO's destructor closes the connection.

PHP
<?php
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

echo "连接中\n";
$pdo = null;          // 立即释放
echo "已释放\n";
Output
连接中
已释放

Friends & Partners