文系プログラマの勉強ノート

スマホアプリ開発やデザインなどについて勉強したことをまとめています

【PHP】PHPからSQLを実行する

PHPからPDO(PHP Data Object)を使用してSQLを実行する手順です。
お決まりの手順ですが、たまにやると手順が抜けたり順番を忘れたりするので、まとめておきます。

トランザクションなしの場合

データベースからデータを検索するサンプルです。

// DB接続
try {
    // ①データベースハンドラ作成
    $pdo = new PDO('mysql:host=localhost;dbname=sampledb;charset=utf8', 'username', 'password');
    // ②エラー属性設定
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  // 例外を発生させる
} catch (PDOException $Exception) {
    die('接続エラー :' . $Exception->getMessage());
}

// 処理実行
try {
    // ③SQL作成
    $sql = "select * from member";
    // ④ステートメントハンドラ作成、処理を実行
    $smth = $pdo->query($sql);
    // 結果を表示
    print "登録されているデータは全部で".$smth->rowCount()."件です。<br>";
} catch (PDOException $Exception) {
    print "エラー:" . $Exception->getMessage();
}
①データベースハンドラ作成

DSN(Data Source Name)を指定してデータベースに接続します。
DSNは以下のような構文で、データベースの種類によって指定できる項目が若干変わります。
(サンプルはMySQLの場合です)

<DSN接頭辞>:host=<ホスト名>;dbname=<データベース名>;charset=<文字コード>
②エラー属性設定

エラーが発生した際にtry catchで例外を検出できるように設定します。

SQL作成

実行したいSQLを記述します。

ステートメントハンドラ作成、処理を実行

このサンプルは用意したSQLをそのまま実行するので、$pdo->query($sql)を使いました。
SQL中に変数を含む場合はプリペアドステートメントというものを使用します。
(後述の「トランザクションありの場合」の方をご覧ください)

ステートメントハンドラ($smth、PDOStatementクラス)を使って実行結果を取得できます。

トランザクションありの場合

トランザクション処理を利用することで、処理実行中は他のユーザーのデータベース更新処理がブロックされます。
また、処理に失敗した場合、ロールバック処理で元の状態に戻すことができます。
データの新規登録、更新、削除などではトランザクション処理を利用すべきでしょう。

トランザクション処理を利用する場合は、処理を$pdo->beginTransactionと$pdo->commit()で囲みます。

以下は、データを新規登録するサンプルです。

// DB接続
try {
    // ①データベースハンドラ作成
    $pdo = new PDO('mysql:host=localhost;dbname=sampledb;charset=utf8', 'username', 'password');
    // ②エラー属性設定
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  // 例外を発生させる
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  // プリペアドステートメントを利用
} catch (PDOException $Exception) {
    die('接続エラー :' . $Exception->getMessage());
}

// 処理実行
try {
    // ③トランザクション開始
    $pdo->beginTransaction();
    // ④SQL、ステートメントハンドラ作成
    $sql = "insert into member (username, password, register_date) values(:username, :password, now())";
    $smth = $pdo->prepare($sql);
    // ⑤データをバインド
    $smth->bindValue(':username', 'test@example.com');
    $smth->bindValue(':password', 'test');
    // ⑥処理を実行
    $smth->execute();
    // ⑦変更を確定
    $pdo->commit();
    // 結果を表示
    print "データを".$smth->rowCount()."件挿入しました。<br>";
} catch (PDOException $Exception) {
    // ⑧元の状態に戻す
    $pdo->rollBack();
    print "エラー:" . $Exception->getMessage();
}
①データベースハンドラ作成

同上。

②エラー属性設定

例外発生の設定に加え、プリペアドステートメント利用の設定をします。

トランザクション開始

処理実行の前にトランザクションを開始します。

SQLステートメントハンドラ作成

初期値を指定してデータを新規登録するSQLを記述します。
最初の()内はカラム名、後の()は初期値です。

username, passwordはログインフォームなどでユーザの入力値を使うことを想定しています。
この場合は、名前付きプレースホルダ(:username, :password)を指定し、後で変数と関連付けます。

register_dateは現在時刻を使うことを想定しています。
このようにメソッドで取得できる値や決め打ちの値を使う場合は、SQL中に直接書けます。

⑤データをバインド

④の名前付きプレースホルダに変数の値を結びつけます。

⑥処理を実行

準備ができたので、SQLを実行します。

⑦変更を確定

変更を確定します。

⑧元の状態に戻す

処理の途中でエラーが発生した場合、$pdo->rollBack()を呼んで処理を元に戻します。