PDOの各種メソッド(1/2)
exec
PDO::execメソッドはSQL文を発行し、変更を行った行数を返すメソッドです。SELECT文の結果は返されません。通常はPDO::prepareを行い、PDOStatement::executeすることが多いでしょう。
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を実行し、それによって変更された行が帰ります。実行結果は以下です。
Update Count: 1
beginTransaction/commit/rollBack
通常はオートコミットがオン(true)になっていますが、beginTransactionを使うと任意の状態でトランザクションを発行することができます。
beginTransactionを実行するとオートコミットはオフになります。
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を実行することができなくなります。
上記のスクリプトを実行した後の結果は以下になります。
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インジェクションを防ぎやすくなります。多くの場合で、一番よく使うメソッドであると思います。
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文が発行されます。
上記の実行結果は以下になります。
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は単一のクエリを実行しますが、順次実行することで連続したデータを取得することができます。
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によって結果セットの形式も順次変更可能です。
上記の実行結果は次のようになります。
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"
}

CONTENT =