提要:PostgreSQL PHP 接口部分向您展示了如何使用PHP数据对象(PDO)API 与 PostgreSQL 数据库进行交互。

使用 PDO 连接到 PostgreSQL 数据库

启用 PDO_PGSQL 驱动

大部分 PHP 发行包默认都包含了 PostgreSQL 驱动:PDO_PGSQL,所以你不需要对 PHP 进行额外的配置。如果你使用的 PHP 没有包含该驱动,可以通过修改 php.ini 文件来启用该驱动,将该行前面的分号去掉:

;extension=php_pdo_pgsql.dll

你只需要将该行前面的分号去掉,并重启 Web 服务器:

extension=php_pdo_pgsql.dll

创建数据库

首先,创建一个名为 sjk66 的数据库作为演示:

CREATE DATABASE sjk66;

下一步,使用 database.ini 文件来保存 PostgreSQL 参数:

host=localhost 
port=5432
database=sjk66
user=postgres
password=sjk66.com

连接数据库

<?php
//get_pdo.php
function get_pdo(){
    $params = parse_ini_file('database.ini'); // 从配置文件载入配置信息
    if ($params === false){
        throw new Exception('错误,读取配置文件失败。');
    }
    $conn_str = sprintf("pgsql:host=%s;port=%d;dbname=%s;user=%s;password=%s", 
                    $params['host'], 
                    $params['port'], 
                    $params['database'], 
                    $params['user'], 
                    $params['password']);
    $pdo = new PDO($conn_str);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $pdo;
}

然后,在 index.php 里获取该连接:

<?php
// index.php
require 'get_pdo.php';

$conn = null;

try {
    $conn = get_pdo();
    echo '连接 PostgreSQL 服务器成功!';
} catch (PDOException $e){
    echo $e->getMessage();
}

运行 index.php,如果一切顺利的话,你将看到以下信息:

连接 PostgreSQL 服务器成功!

如果你看到不是这个成功信息,请确保启用了 pdo_pgsql 驱动,或修改 database.ini 里的配置信息。

当密码错误时,显示以下信息:

SQLSTATE[08006] [7] FATAL: password authentication failed for user "postgres"

当数据库不存在时,显示以下信息:

SQLSTATE[08006] [7] FATAL: database "sjk66" does not exist

创建新表

让我们来创建2个新表:

CREATE TABLE IF NOT EXISTS stocks (
    id SERIAL PRIMARY KEY,
    symbol CHARACTER VARYING(10) NOT NULL UNIQUE,
    company CHARACTER VARYING(255) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS stock_valuations (
    stock_id INTEGER NOT NULL,
    value_on DATE NOT NULL,
    price NUMERIC(8 , 2 ) NOT NULL DEFAULT 0,
    PRIMARY KEY (stock_id , value_on),
    FOREIGN KEY (stock_id)
        REFERENCES stocks (id)
);

插入数据

插入单条记录

下面的 insert_stock() 函数用于向 stock 表添加单条数据:

<?php
// index.php

function insert_stock($symbol, $company) {
    $sql = 'INSERT INTO stocks(symbol,company) VALUES(:symbol,:company)';

    try {
        $conn = get_pdo();
        $stmt = $conn->prepare($sql);

        // 绑定参数
        $stmt->bindValue(':symbol', $symbol);
        $stmt->bindValue(':company', $company);

        // 执行
        $stmt->execute();

        // 返回生成的ID
        return $conn->lastInsertId('stocks_id_seq');
    } catch (PDOException $e){
        echo $e->getMessage();
    }
}

插入多条记录

下面的 insert_stock_list() 函数用于向 stock 表添加多条数据:

<?php
// index.php

function insert_stock_list($stocks) {
    $sql = 'INSERT INTO stocks(symbol,company) VALUES(:symbol,:company)';

    try {
        $conn = get_pdo();
        $stmt = $conn->prepare($sql);

        $id_list = [];
        foreach($stocks as $stock){
            $stmt->bindValue(':symbol', $stock['symbol']);
            $stmt->bindValue(':company', $stock['company']);
            $stmt->execute();

            $id_list[] = $conn->lastInsertId('stocks_id_seq');
        }
        return $id_list;
    } catch (PDOException $e){
        echo $e->getMessage();
    }
}

下面是使用以上两个函数的示例:

<?php
//index.php
$id = insert_stock('MSFT', 'Microsoft Corporation');
echo 'The stock has been inserted with the id ' . $id . '<br>';

$list = insert_stock_list([
    ['symbol' => 'GOOG', 'company' => 'Google Inc.'],
    ['symbol' => 'YHOO', 'company' => 'Yahoo! Inc.'],
    ['symbol' => 'FB', 'company' => 'Facebook, Inc.'],
]);
foreach ($list as $id) {
    echo 'The stock has been inserted with the id ' . $id . '<br>';
}

结果如下:

The stock has been inserted with the id 1
The stock has been inserted with the id 2
The stock has been inserted with the id 3
The stock has been inserted with the id 4

修改记录

下面的 update_stock() 用于修改 stock 表中指定id的数据:

<?php
// index.php
function update_stock($id, $symbol, $company) {
    $sql = 'UPDATE stocks '
                . 'SET company = :company, '
                . 'symbol = :symbol '
                . 'WHERE id = :id';
    $conn = get_pdo();
    $stmt = $conn->prepare($sql);

    $stmt->bindValue(':symbol', $symbol);
    $stmt->bindValue(':company', $company);
    $stmt->bindValue(':id', $id);

    $stmt->execute();

    return $stmt->rowCount();
}

查询记录

查询所有记录

下面的 all() 函数用于查询 stocks 表中的所有记录:

<?php
//index.php

function all(){
    $conn = get_pdo();
    $stmt = $conn->prepare('SELECT id, symbol, company '
                . 'FROM stocks '
                . 'ORDER BY symbol');
    $stocks = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $stocks[] = [
            'id' => $row['id'],
            'symbol' => $row['symbol'],
            'company' => $row['company']
        ];
    }
    return $stocks;
}

查询指定记录

下面的 find_by_id() 函数返回指定id的单条记录:

<?php
//index.php
function find_by_id($id){
    $conn = get_pdo();
    $stmt = $conn->prepare('SELECT id, symbol, company
                                       FROM stocks
                                      WHERE id = :id');
    $stmt->bindValue(':id', $id);
    $stmt->execute();

    return $stmt->fetchObject();
}

删除记录

删除单条记录

下面的 delete() 函数用于删除指定id的记录:

<?php
//index.php
function delete($id){
    $conn = get_pdo();
    $stmt = $conn->prepare('DELETE FROM stocks WHERE id = :id');
    $stmt->bindValue(':id', $id);
    $stmt->execute();

    return $stmt->rowCount();
}

删除所有记录

下面的 delete_all() 函数用于删除所有记录:

<?php
//index.php
function delete_all(){
    $conn = get_pdo();
    $stmt = $conn->prepare('DELETE FROM stocks');
    $stmt->execute();

    return $stmt->rowCount();
}