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" }