前回の記事でPHP内でDBに接続する方法について説明しました。
今回は接続後にデータを取得したり更新したりする処理について解説します。
DB操作の種類
まずDB操作と言っても種類が4種類あります。
4種類というのは、Create(作成)、Read(参照)、Update(更新)、Delete(削除)の頭文字をとってCRUDです。
これは設計段階で、各機能がどのテーブルに対しどんな操作を行うかでも定義されます。
Readの参照は、DB内のデータが何も書き変わることが無いので失敗しても「失敗しちゃった!」で修正するだけです。
しかし、更新や作成、削除の場合はDB内が書き変わるため万が一失敗したら更新処理を走らせる前の状態に戻す必要があります。
これをロールバックと言います。
髪の毛を全部後ろにやるやつじゃないですよ!・・・なんでもないです。
そして、DBに対しSQLを投げて結果を得るまでの一連の流れのことをトランザクションと言います。
トランザクションは「一連のやり取り」のような意味なので、もっと大きな意味で画面上のボタンを押してから次の画面が開くまでを指したりもしますが、一般的にはDB処理のことをいいます。
DBからデータを取得する
<?php
// DB接続情報
$user = 'root';
$pass = '2222';
$dbnm = 'shopping';
$host = 'localhost';
// 接続先DBリンク
$connect = "mysql:host={$host};dbname={$dbnm}";
try {
// DB接続
$pdo = new PDO($connect, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<p>DB接続に成功しました。</p>";
// SQL実行
$sql = "SELECT id, user_name FROM user";
$stmt = $pdo->prepare($sql);
$stmt->execute();
// 結果の取得
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
//var_dump($result);
} catch (Exception $e) {
echo "<p>DB接続エラー</p>";
echo $e->getMessage();
exit();
}
?>
<table>
<tr>
<th>ID</th>
<th>ユーザー名</th>
</tr>
<?php foreach ($result as $row) {?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['user_name']; ?></td>
</tr>
<?php } ?>
</table>
16行目まではDB接続です。
18行目からSELECT文の実行になります。
SQLを作成し、PDOオブジェクト($pdo)の prepare() にセットします。
そして戻り値のプリペアードステートメント($stmt)の execute() を呼び出し実行します。
そして24行目でSELECTの結果を取得します。
32~43行目で取得したSQL実行結果をテーブルに出力します。
<?php foreach ($result as $row) {?>
は、SQL実行結果が連想配列で取得出来るため、foreach を使って全部ループします。
1行1行のデータが $row に入り、
<?php echo $row['id']; ?>
と書くことでHTMLに出力することができます。
ループ内に
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['user_name']; ?></td>
</tr>
のように書くことで、データの件数だけHTMLのテーブルの行を増やしていくことが出来ます。
DBにデータを登録、更新、削除する
<?php
// DB接続情報
$user = 'root';
$pass = '2222';
$dbnm = 'shopping';
$host = 'localhost';
// 接続先DBリンク
$connect = "mysql:host={$host};dbname={$dbnm}";
try {
// DB接続
$pdo = new PDO($connect, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<p>DB接続に成功しました。</p>";
// SQL実行
$sql = "UPDATE product SET price = price + 10 WHERE id = 1";
$stmt = $pdo->prepare($sql);
$pdo->beginTransaction();
try {
$stmt->execute();
$pdo->commit();
} catch (PDOException $e) {
echo "<p>DB更新エラー</p>";
//ロールバック
$pdo->rollback();
echo $e->getMessage();
}
} catch (Exception $e) {
echo "<p>DB接続エラー</p>";
echo $e->getMessage();
exit();
}
?>
サンプルコードでは更新を行っていますが、登録も削除もDBを書き換えるので同じように書きます。
参照と違うところは、21行目で
$pdo->beginTransaction();
と、トランザクション開始の指示を出して、実行部分を try catch で囲んでいるところです。
そしてSQL実行時に何か問題があれば 26 行目の
} catch (PDOException $e) {
でキャッチされ、29行目
$pdo->rollback();
でロールバックされます。
ただ上記のようなシンプルなものだとロールバックされるようなエラーが思い浮かばないですが・・・。
実際にはもっとたくさんの処理が走るためサンプルコードのようにしっかりロールバックされるようにしましょう。
まとめ
今回の記事も記憶を叩き起こしながら過去に作成したコードなどを参考に書きました。
というのも実はあまり上記のようなコードを書く場面が無いのです。
最近はWEBシステムの構築にはほぼ100%フレームワークが使われており、フレームワーク内で上記のようなことが実行されます。
では何故ながながと説明したのか!
それはフレームワークを使えば上記のようなコードが削減できますが、そういったことが行われていることは知っておいたほうがいいからです。
具体的なコードは忘れたらまたこのページを見ればよいです。
しかし、DB操作には CRUD と呼ばれる4種類の操作があり、そのうちCUDはDBを書き換えることになります。
その場合にはロールバックが無いと後々大変なことになるということだけでも今回は覚えておいてください。










コメント