Skip to content

PostgreSQL - PHP

将 PHP 应用程序连接到 PostgreSQL 数据库是常见的需求。现代、安全且推荐的方法是使用 PHP 数据对象(PDO),它是一个抽象层,为数据库访问提供了统一而强大的接口。

在连接之前,请确保您的 PHP 安装中已启用 PDO PostgreSQL 驱动。您可以通过在终端中运行 php -m | grep pdo_pgsql 来检查,或者在 php.ini 文件中查找以下行(并确保它没有被注释掉):

extension=pdo_pgsql

在使用 Docker 的现代开发环境中,您通常会在 Dockerfile 中安装并启用此扩展。

通过创建 PDO 类的实例来建立连接。将此逻辑包装在 try...catch 块中以优雅地处理潜在的连接错误至关重要。

<?php
$host = '127.0.0.1';
$port = '5432';
$dbname = 'testdb';
$user = 'postgres';
$password = 'your_password'; // 最佳实践:使用环境变量!
// 数据源名称(DSN)
$dsn = "pgsql:host=$host;port=$port;dbname=$dbname";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 将结果作为关联数组获取
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $password, $options);
echo "Connected to the $dbname database successfully!";
} catch (\PDOException $e) {
// 在实际应用中,应记录此错误而不是直接输出
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
// $pdo 对象现在已准备好进行查询
?>

您将使用 PDO 对象上的方法,而不是过程式函数。以下是最重要的几个:

方法描述
prepare(string $query)准备一个 SQL 语句以供执行。这是防止 SQL 注入的第一步。
execute(array $params = null)执行一个预处理语句,可选地传递一个参数数组进行绑定。
query(string $query)直接执行一个 SQL 语句并返回结果集。仅用于不含用户输入的查询。
fetch()从结果集中获取下一行。
fetchAll()返回一个包含所有结果集行的数组。
rowCount()返回上一个 DELETE、INSERT 或 UPDATE 语句影响的行数。
lastInsertId(string $name = null)返回最后插入行的 ID,如果需要可指定序列名称。

出于安全考虑,使用预处理语句是不可妥协的。它将 SQL 查询与数据分离,从而使 SQL 注入不可能发生。

<?php
// 假设使用上面创建的 $pdo 连接对象
$sql = 'INSERT INTO company (name, age, address, salary) VALUES (:name, :age, :address, :salary)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
'name' => 'Allen',
'age' => 25,
'address' => 'Texas',
'salary' => 15000.00
]);
$lastId = $pdo->lastInsertId('company_id_seq'); // 注意:可能需要序列名称
echo "New record created successfully. Last inserted ID is: " . $lastId;
?>
<?php
// 假设使用 $pdo 连接对象
$sql = 'SELECT id, name, salary FROM company WHERE age > ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([24]);
$companies = $stmt->fetchAll();
foreach ($companies as $company) {
echo $company['id'] . ' | ' . $company['name'] . ' | $' . $company['salary'] . "\n";
}
?>
<?php
// 假设使用 $pdo 连接对象
$sql = 'UPDATE company SET salary = :salary WHERE id = :id';
$stmt = $pdo->prepare($sql);
$stmt->execute([
'salary' => 25000.00,
'id' => 1
]);
echo $stmt->rowCount() . " record(s) updated successfully.";
?>
<?php
// 假设使用 $pdo 连接对象
$sql = 'DELETE FROM company WHERE id = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([2]);
echo $stmt->rowCount() . " record(s) deleted successfully.";
?>
  • 安全存储凭证:切勿在代码中硬编码数据库凭证。使用环境变量(例如,通过 .env 文件和像 vlucas/phpdotenv 这样的库)并在运行时加载它们。
  • 错误处理:始终使用 PDO::ERRMODE_EXCEPTION 并将您的数据库逻辑包装在 try...catch 块中。在生产环境中将错误记录到文件,而不是直接显示给用户。
  • 连接管理:对于 Web 应用程序,在应用程序启动时建立单个数据库连接,并在整个请求生命周期中重用 $pdo 对象。避免在循环或每个函数中进行连接。
  • 使用 Composer:使用 Composer(PHP 的标准包管理器)管理您的项目依赖,包括任何与数据库相关的库或 ORM。