PHP PDOのスニペット集

このページは、PHPのPDOのスニペットなどをまとめる予定のページです。

目次

注意

  • コードのライセンスはCC0 (クレジット表示不要、改変可、商用可) です。

スニペット

PDO の生成

MySQL
$host = 'localhost';
$dbname = 'demo';
$user = 'root';
$password = 'pass';
$charset = 'utf8';
$dsn = "mysql:host={$host};dbname={$dbname};charset={$charset}";
$pdo = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
PostgreSQL
$host = 'localhost';
$dbname = 'demo';
$user = 'postgres';
$password = 'postgres';
$charset = 'UTF8';
$dsn = "pgsql:host={$host};dbname={$dbname};options='--client_encoding={$charset}'";
$pdo = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);

setAttribute()

※ コンストラクタの引数で指定しても可

エラー時に例外を発生させる
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
オブジェクト形式でデータを取得するよう設定
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
連想配列形式でデータを取得するよう設定
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

getAttribute()

ドライバー名 ('mysql' など) の取得
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);

パラメータのバインド

execute()でのバインド (string (PDO::PARAM_STR) としてバインド)
$stmt = $pdo->prepare('SELECT * FROM user WHERE id = :id');
$stmt->execute(array('id' => 1)); // バインドと実行
bindValue()でのバインド
$stmt = $pdo->prepare('SELECT * FROM user WHERE name LIKE :name LIMIT :limit');
$stmt->bindValue('name', '%a%'); // PDO::PARAM_STR でのバインド (値がintでもstringになる)
$stmt->bindValue('name', '%a%', PDO::PARAM_STR); // ↑と同じ
$stmt->bindValue('limit', 1, PDO::PARAM_INT); // PDO::PARAM_INT でのバインド (値がintでないとintで渡らない)
$stmt->execute(); // 実行

SQL の実行

SELECT
$st = $pdo->prepare('SELECT * FROM user WHERE gender = :gender');
$st->execute(array('gender' => 1));
$rowArray = $st->fetchAll();
SELECT 1件
$st = $pdo->prepare('SELECT * FROM user WHERE id = :id');
$st->execute(array('id' => 1));
$row = $st->fetch();
UPDATE など
$st = $pdo->prepare('UPDATE user SET username = :username WHERE id = :id');
$st->execute(array('username' => 'test', 'id' => 1));

トランザクション

コミット
$pdo->beginTransaction();

// SQL 処理...

$pdo->commit();
ロールバック
$pdo->beginTransaction();

// SQL 処理...

$pdo->rollBack();

直近の INSERT ID の取得

$id = $pdo->lastInsertId();

ユーティリティ関数

PDO 簡易関数

ORMやクエリビルダなどのライブラリを使うまでもない場合に使用するための関数です。

<?php
/**
 * PDOを生成します。
 * @param array|string $params DSN生成用のパラメータまたはDSN文字列
 * @param string $user DBユーザー名
 * @param string $password DBパスワード
 * @param array $options PDOオプション
 * @return PDO
 */
function pdo($params, $user = null, $password = null, array $options = array()) {
    // DSN文字列指定の場合はそのまま使用
    if (is_string($params)) $dsn = $params;
    // その他の場合はDSN文字列化 (MySQL等)
    else {
        $dsn = strtolower($params['driver']) . ':';
        // SQLite: source にあるファイルパスまたは:memory:をセット
        if ($dsn == 'sqlite:') $dsn .= $params['source'];
        // その他: パラメータを文字列化 (mysql:dbname=testdb;host=localhost 等)
        else foreach ($params as $k => $v) $dsn .= "{$k}={$v};";
    }
    $user = (is_array($params) && isset($params['user'])) ? $params['user'] : $user;
    $password = (is_array($params) && isset($params['password'])) ? $params['password'] : $password;
    return new PDO($dsn, $user, $password, $options);
}
/**
 * クエリ(SELECT, INSERT, UPDATE, DELETE)を実行します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return PDOStatement
 */
function pdo_query(PDO $pdo, $query, array $params = array()) {
    $keys = array_keys($params);
    $isAssoc = ($keys !== range(0, count($keys)-1));

    $st = $pdo->prepare($query);
    foreach ($params as $k => $v) {
        $name = ($isAssoc) ? ':' . $k : ($k + 1);
        $dataType = (!is_string($v) && is_int($v)) ? PDO::PARAM_INT : PDO::PARAM_STR;
        $st->bindValue($name, $v, $dataType);
    }
    $st->execute();
    return $st;
}
/**
 * クエリ(主にSELECT文)を実行し、結果を配列で取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return array
 */
function pdo_query_all(PDO $pdo, $query, array $params = array()) { return pdo_query($pdo, $query, $params)->fetchAll(); }
/**
 * クエリ(主にSELECT文)を実行し、結果を1行取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return mixed
 */
function pdo_query_one(PDO $pdo, $query, array $params = array()) { return pdo_query($pdo, $query, $params)->fetch(); }
/**
 * クエリ(主にSELECT文)を実行し、結果の先頭行の先頭列の値を1つ取得します。
 * @param PDO $pdo 対象PDO
 * @param string $query SQL文
 * @param array $params SQL文のパラメータ
 * @return mixed
 */
function pdo_query_var(PDO $pdo, $query, array $params = array()) { $row = pdo_query($pdo, $query, $params)->fetch(PDO::FETCH_NUM); return $row ? $row[0] : false; }
/**
 * INSERT文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param array $fields 列名と値を持つ連想配列 (array('id' => 1) 等)
 * @return int
 */
function pdo_insert(PDO $pdo, $table, array $fields) {
    $keys = array_keys($fields);
    $fieldInfo = '';
    $isAssoc = ($keys !== range(0, count($keys)-1));
    if ($isAssoc) {
        $q = ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') ? '`' : '"';
        foreach ($keys as $k) {
            $fieldInfo .= ", {$q}{$k}{$q}";
        }
        $fieldInfo = '(' . substr($fieldInfo, 2) . ')';
    }
    $st = $pdo->prepare("INSERT INTO {$table}{$fieldInfo} VALUES (" . implode(', ', array_fill(0, count($keys), '?')) . ')');
    $st->execute(array_values($fields));
    return $st->rowCount();
}
/**
 * UPDATE文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param array $fields 列名と値を持つ連想配列 (array('id' => 1) 等)
 * @param string $where WHERE句 ('id = ?', 'id = :id' 等)
 * @param array $params WHERE句のパラメータ (array(1), array('id' => 1) 等)
 * @return int
 */
function pdo_update(PDO $pdo, $table, array $fields, $where = null, array $params = array()) {
    $q = ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') ? '`' : '"';
    $paramKeys = array_keys($params);
    $isParamsAssoc = ($paramKeys !== range(0, count($paramKeys)-1));

    $fieldInfo = '';
    $newFields = array();
    // フィールドパラメータを WHERE パラメータに合わせる (連想配列か通常配列)
    if ($isParamsAssoc) {
        $i = 1;
        foreach ($fields as $k => $v) {
            $newFieldKey = '__' . $i;
            $newFields[$newFieldKey] = $v;
            $fieldInfo .= ", {$q}{$k}{$q}=:{$newFieldKey}";
            $i++;
        }
    }
    else {
        foreach ($fields as $k => $v) {
            $newFields[] = $v;
            $fieldInfo .= ", {$q}{$k}{$q}=?";
        }
    }
    $fieldInfo = substr($fieldInfo, 2);
    $params = array_merge($newFields, $params);
    $st = $pdo->prepare("UPDATE {$table} SET {$fieldInfo}" . ($where ? " WHERE {$where}" : ''));
    $st->execute($params);
    return $st->rowCount();
}
/**
 * DELETE文を実行します。(引数からSQLを生成して実行します)
 * @param PDO $pdo 対象PDO
 * @param string $table 対象テーブル名
 * @param string $where WHERE句 ('id = ?', 'id = :id' 等)
 * @param array $params WHERE句のパラメータ (array(1), array('id' => 1) 等)
 * @return int
 */
function pdo_delete(PDO $pdo, $table, $where = null, array $params = array()) {
    $st = pdo_query($pdo, "DELETE FROM {$table}" . ($where ? " WHERE {$where}" : ''), $params);
    return $st->rowCount();
}
使用例
// PDO生成

$pdo = pdo(array('driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'user' => 'root', 'password' => 'root', 'charset' => 'utf8'));
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); // オブジェクトでデータ取得
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // エラー時に例外

$pdo->beginTransaction();

$userId = 1;

// CREATE TABLE

pdo_query($pdo, 'DROP TABLE IF EXISTS user');
if ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
    pdo_query($pdo, 'CREATE TABLE IF NOT EXISTS user ( id SERIAL, name VARCHAR(255), `group` INTEGER )');
}
else {
    pdo_query($pdo, 'CREATE TABLE IF NOT EXISTS user ( id SERIAL, name VARCHAR(255), "group" INTEGER )');
}

// DELETE

// DELETE FROM user WHERE id IN (1, 2)
$rowCount = pdo_delete($pdo, 'user', 'id IN (:id, :id + 1)', array('id' => $userId));
echo '削除件数: ' . $rowCount . PHP_EOL;

// INSERT

// INSERT INTO VALUES (1, '山田', 1) -- 列名未指定形式
$rowCount  = pdo_insert($pdo, 'user', array($userId, '山田', 1));
// INSERT INTO (id, name, group) VALUES (2, '鈴木', 2) -- 列名指定形式 (列名はエスケープ)
$rowCount += pdo_insert($pdo, 'user', array('id' => $userId + 1, 'name' => '鈴木', 'group' => 2));
echo '挿入件数: ' . $rowCount . PHP_EOL;

// UPDATE

// UPDATE user SET name = '山田2', group = 2 WHERE id = 1 -- '?' プレースホルダ形式
$rowCount  = pdo_update($pdo, 'user', array('name' => '山田2', 'group' => 2), 'id = ?', array($userId)); 
// UPDATE user SET name = '鈴木2', group = 3 WHERE id = 2 -- ':xxx' プレースホルダ形式
$rowCount += pdo_update($pdo, 'user', array('name' => '鈴木2', 'group' => 3), 'id = :id', array('id' => $userId + 1));
echo '更新件数: ' . $rowCount . PHP_EOL;

// SELECT (一覧)

// SELECT * FROM user WHERE IN (:id, :id + 1) -- ':xxx' プレースホルダ形式 ('?' でも可)
$users = pdo_query_all($pdo, 'SELECT * FROM user WHERE id IN (:id, :id + 1)', array('id' => $userId));
echo '取得データ(一覧): ' . PHP_EOL;
echo json_encode($users, JSON_UNESCAPED_UNICODE) . PHP_EOL;

// SELECT (1件)

// SELECT * FROM user WHERE id = 1 -- '?' プレースホルダ形式 (':xxx' でも可)
$user = pdo_query_one($pdo, 'SELECT * FROM user WHERE id = ?', array($userId));
echo '取得データ(1件): ' . PHP_EOL;
echo json_encode($user, JSON_UNESCAPED_UNICODE) . PHP_EOL;

// SELECT (値)

// SELECT COUNT(*) FROM user -- パラメータ指定しても可
$count = pdo_query_var($pdo, 'SELECT COUNT(*) FROM user');
echo '件数: ' . $count . PHP_EOL;

$pdo->commit();