SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

PDOでサクサクDB開発

データベースへのアクセスを抽象化するPHP Data Objectの利用


  • X ポスト
  • このエントリーをはてなブックマークに追加

PDOの各種メソッド(1/2)

exec

 PDO::execメソッドはSQL文を発行し、変更を行った行数を返すメソッドです。SELECT文の結果は返されません。通常はPDO::prepareを行い、PDOStatement::executeすることが多いでしょう。

pdo_exec
try {
    $pdo = CZ_PDO::getConnection();
    $count = $pdo->exec("UPDATE CD SET TITLE = 'BERCEUSE',
                        CONTENT = 'CRADLE SONG' WHERE ID = 5");
    echo "Update Count: " . $count . PHP_EOL;
} catch (PDOException $e) {
    var_dump($e);
}

 上記の例では、UPDATEを実行し、それによって変更された行が帰ります。実行結果は以下です。

result
Update Count: 1

beginTransaction/commit/rollBack

 通常はオートコミットがオン(true)になっていますが、beginTransactionを使うと任意の状態でトランザクションを発行することができます。

 beginTransactionを実行するとオートコミットはオフになります。

transaction
try {
    $pdo = CZ_PDO::getConnection();
    // トランザクションを開始します。
    // (オートコミットは自動的にオフになります)
    $pdo->beginTransaction();

    $pdo->exec(
"INSERT INTO CD(ID, TITLE, CONTENT) VALUES(8, 'FOO', 'FOO SONG')");
    $pdo->exec(v
"INSERT INTO CD(ID, TITLE, CONTENT) VALUES(9, 'BAR', 'BAR SONG')");

    // 重複キーでINSERT文を発行します。
    $pdo->exec(
"INSERT INTO CD(ID, TITLE, CONTENT) VALUES(1, 'BAZ', 'BAZZ SONG')");

    // トランザクションをコミットします。commit後、
    // beginTransactionのが終了しオートコミットに戻ります。
    $pdo->commit();
} catch (PDOException $e){
    echo "Catch Exception!" . PHP_EOL;
    // ロールバックを発行し、beginTransaction前の結果に戻します。
    $pdo->rollBack();
    var_dump($pdo->query("SELECT * FROM CD")
                 ->fetchAll(PDO::FETCH_ASSOC));
}

 上記のスクリプトでは、beginTransactionでトランザクションを開始しINSERT文を発行していますが、重複キーがあるため、PDOExceptionが発生します。catch内でrollBackを実行しているのでbeginTransaction前の状態に戻ります。

 また、ここでは実行されませんでしたが、commitを実行すると自動的にbeginTransactionは解除になり、その後にrollBackを実行することができなくなります。

 上記のスクリプトを実行した後の結果は以下になります。

result
Catch Exception!
array(7) {
    [0]=>
    array(3) {
        ["ID"]=>
        string(1) "1"
        ["TITLE"]=>
        string(5) "HAPPY"
        ["CONTENT"]=>
        string(10) "HAPPY SONG"
    }
    [1]=>
    array(3) {
        ["ID"]=>
        string(1) "2"
        ["TITLE"]=>
        string(3) "SAD"
        ["CONTENT"]=>
        string(8) "SAD SONG"
    }
    [2]=>
    array(3) {
        ["ID"]=>
        string(1) "3"
        ["TITLE"]=>
        string(5) "ANGRY"
        ["CONTENT"]=>
        string(10) "ANGRY SONG"
    }
    [3]=>
    array(3) {
        ["ID"]=>
        string(1) "4"
        ["TITLE"]=>
        string(4) "LOVE"
        ["CONTENT"]=>
        string(9) "LOVE SONG"
    }
    [4]=>
    array(3) {
        ["ID"]=>
        string(1) "5"
        ["TITLE"]=>
        string(6) "SLEEPY"
        ["CONTENT"]=>
        string(11) "SLEEPY SONG"
    }
    [5]=>
    array(3) {
        ["ID"]=>
        string(1) "6"
        ["TITLE"]=>
        string(9) "CHRISTMAS"
        ["CONTENT"]=>
        string(14) "CHRISTMAS SONG"
    }
    [6]=>
    array(3) {
        ["ID"]=>
        string(1) "7"
        ["TITLE"]=>
        string(8) "NEW YEAR"
        ["CONTENT"]=>
        string(13) "NEW YEAR SONG"
    }
}

prepare

 PDO::prepareはSQLを解釈し、PDOStatementのオブジェクトを返します。PDO::prepareは一度SQLを解釈しキャッシュしているので、複数回実行されるようなSQLを発行する場合に向いています。

 また、PDO::prepareはSQL文とそのパラメータを解釈しますので、自前でSQLをパースする場合に比べSQLインジェクションを防ぎやすくなります。多くの場合で、一番よく使うメソッドであると思います。

prepare
try {
    $pdo = CZ_PDO::getConnection();

    // PDO::prepareによってPDOStatementオブジェクトが返されます。
    $stmt = $pdo->prepare(
"INSERT INTO CD(ID, TITLE, CONTENT) VALUES(?, ?, ?)");
    // パラメータ '?' に値を設定し実行(execute)します。
    $stmt->bindValue(1, 10);
    $stmt->bindValue(2, "Hoge");
    $stmt->bindValue(3, "Hoge Song");
    $stmt->execute();

    // 他のパラメータを代入し実行します。
    $stmt->bindValue(1, 11);
    $stmt->bindValue(2, "Foo");
    $stmt->bindValue(3, "Foo Song");
    $stmt->execute();

    //PDOStatementオブジェクトを開放します。
    $stmt = null;

    // SELECT文にも使えます。
    $stmt2 = $pdo->prepare("SELECT * FROM CD WHERE ID = :ID");
    $stmt2->bindValue(":ID", 10);
    $stmt2->execute();
    var_dump($stmt2->fetch(PDO::FETCH_ASSOC));

    $stmt2->bindValue(":ID", 11);
    $stmt2->execute();
    var_dump($stmt2->fetch(PDO::FETCH_ASSOC));
} catch (PDOException $e) {
    var_dump($e->getMessage());
}

 上記の例では、INSERT文とSELECT文のSQLを複数回実行しています。

 PDO::prepareによって返されるPDOStatementオブジェクトにパラメータ('?':ID)と対となる値を設定し、executeすることでSQL文が発行されます。

 上記の実行結果は以下になります。

result
array(3) {
    ["ID"]=>
    string(2) "10"
    ["TITLE"]=>
    string(4) "Hoge"
    ["CONTENT"]=>
    string(9) "Hoge Song"
}
array(3) {
    ["ID"]=>
    string(2) "11"
    ["TITLE"]=>
    string(3) "Foo"
    ["CONTENT"]=>
    string(8) "Foo Song"
}

query

 PDO::queryはSQL文を実行し、その結果をPDOStatementに格納します。PDO::queryは一見PDO::prepareと同じような動きをしますが、PDOStatement::executeを実行しなくともPDOStatement::executeの発行後のSQLの結果セットをPDOStatementに格納します。

 また、PDO::queryは単一のクエリを実行しますが、順次実行することで連続したデータを取得することができます。

query
try {
    $pdo = CZ_PDO::getConnection();

    $stmt = $pdo->query("SELECT * FROM CD");

    // 一つめの結果セットを取得します。
    $rows1 = $stmt->fetch(PDO::FETCH_ASSOC);
    var_dump($rows1);

    // 同様に2つめの結果セットを取得
    $rows2 = $stmt->fetch(PDO::FETCH_ASSOC);
    var_dump($rows2);

    // 結果セットの形式を変更することもできます。
    $rows3 = $stmt->fetch(PDO::FETCH_OBJ);
    var_dump($rows3);

    // ステートメントの開放を行います。
    $stmt = null;
} catch (PDOException $e) {
    var_dump($e->getMessage());
}

 上記の例では、SELECT文の発行で取得される結果セットの1行めから3行めまでを取得しています。PDO::queryで発行されたPDOStatementによって結果セットの形式も順次変更可能です。

 上記の実行結果は次のようになります。

result
array(3) {
    ["ID"]=>
    string(1) "1"
    ["TITLE"]=>
    string(5) "HAPPY"
    ["CONTENT"]=>
    string(10) "HAPPY SONG"
}
array(3) {
    ["ID"]=>
    string(1) "2"
    ["TITLE"]=>
    string(3) "SAD"
    ["CONTENT"]=>
    string(8) "SAD SONG"
}
object(stdClass)#3 (3) {
    ["ID"]=>
    string(1) "3"
    ["TITLE"]=>
    string(5) "ANGRY"
    ["CONTENT"]=>
    string(10) "ANGRY SONG"
}

次のページ
PDOの各種メソッド(2/2)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

ハタ(ハタ)

PHPの魅力に取り付かれた一人。現在はSeasar.PHPとしてSeasar(Java)をPHP5に移植する活動をしている。http://blog.xole.net/(ブログ)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/433 2007/12/13 16:05

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング