【PHP】これで分かる関数! – データの登録 –

PHP

はじめに

この記事で紹介するサンプルプログラムは次の記事で書いている共通関数を使用している場合があります。

データの登録

この記事では、PDOを使用したデータの登録について次のサンプルプログラムを紹介します。

  • PDO::exec()を使用したデータの登録
  • プリペアドステートメントを使用したデータの登録

データ登録等のテーブル更新を行うプログラムはトランザクション処理を使用します。
トランザクション処理はデータの登録中にエラーが発生した場合、データ更新前の状態に戻す(ロールバック)、データ登録が正常に完了した場合、更新後の状態にする(コミット)ことができます。

トランザクション処理はついて説明すると長くなるため、詳しいことを知りたい方は次のPHPマニュアルを見てください。

PHP: トランザクションおよび自動コミット - Manual

マニュアルは文章だけのため、分かりにくいかもしれません。
その場合、ネットでデータベース トランザクション処理などの単語で調べてみてください。

データ登録処理の流れ

データ登録処理の流れは次のように

1.データベースに接続する。

2.トランザクション処理を開始する。
トランザクション処理の開始は次のようにPDO:: beginTransaction()を使用する。

 $pdo->beginTransaction();

3.データの登録SQLを実行する。
・プリペアドステートメントを使用しない場合
次のようにPDO:exec()を使用する。

$pdo->exec("INSERT文");

・プリペアドステートメントを使用する場合
データの検索と同様にPDO::prepare()でSQL文を組み立ててPDOStatement::execute()でSQLを実行する。

4.データ登録の実行後、コミット処理、またはロールバック処理を行う。
次のように、コミット処理はtryブロック内にPDO::commit()、 ロールバック処理はcatchブロック内にPDO::rollBack()を書くことが一般的です。

try {
    // データの登録処理
    // コミット
    $pdo->commit();
} catch(PDOException $e) {
    // ロールバック
    $pdo->rollBack();
}

サンプルプログラム

サンプルプログラムは次の2パターンで紹介します。
サンプルプログラムは商品テーブル(GOODS)、商品分類関連テーブル(GOODS_CLASSES_RELARATION)の2テーブルへのデータ登録を行っています。

1. プリペアドステートメントを使用しない
入力画面の「登録01」ボタンを押下すると、プリペアドステートメントを使用しない登録結果画面①に遷移する

2. プリペアドステートメントを使用する
入力画面の「登録02」ボタンを押下すると、プリペアドステートメントを使用する登録結果画面②に遷移する

プリペアドステートメントを使用しないサンプルプログラム

プリペアドステートメントを使用しないサンプルプログラムです。

・画面

・入力画面のコード

<?php
    // 引数の値への厳密な型付け
    declare(strict_types = 1);
    // 共通ライブラリの読み込み
    require_once __DIR__ . "../../../lib/sample_common.php";
    $filename = basename(__FILE__);
 
    // 共通HTMLヘッダ出力処理
    common_html_header($filename);
 
    echo "ファイル名:${filename}<br>\n";
    echo "テーブルの登録1・入力画面<br>\n";
?>
<form id="sendfrm" action="sample02_09_03_12.php", method="POST">
<table border="1" width="450px">
    <tr>
        <th width="100px">商品コード</th>
        <td><input type="text" name="code" style="width:150px;" maxlength="10"></td>
    </tr>
    <tr>
        <th width="100px">商品分類</th>
        <td>
            <select name="goods_class" style="height:20px; width:200px;">
                <option value="">未選択</option>
                <option value="1001">1001:文房具</option>
                <option value="2001">2001:お菓子</option>
                <option value="3001">3001:おもちゃ</option>
            </select>
        </td>
    </tr>
    <tr>
        <th>商品名</th>
        <td><input type="text" name="name" style="width:300px;" maxlength="100"></td>
    </tr>
    <tr>
        <th>価格</th>
        <td><input type="text" name="price" style="width:100px;" maxlength="11"></td>
    </tr>
    <tr>
        <th>開始日</th>
        <td><input type="text" name="sdate" style="width:100px;" maxlength="8"></td>
    </tr>
    <tr>
        <th>終了日</th>
        <td><input type="text" name="edate" style="width:100px;" maxlength="8"></td>
    </tr>
</table>
<br>
<input type="button" name="send" value="登録01" style="width: 100px;" onclick="open_next(12)">
<input type="button" name="send" value="登録02" style="width: 100px;" onclick="open_next(13)">
</form>

<script>
function open_next(id) {
    var frm = document.getElementById("sendfrm");

    frm.action = "sample02_09_03_" + id + ".php";
    frm.submit();
}
</script>

<?php
    // 共通HTMLフッター出力処理
    common_html_footer();
?>

・登録結果画面①のコード
登録結果画面①はSQLインジェクション対応済みのコードです。

<?php
    // 引数の値への厳密な型付け
    declare(strict_types = 1);
    // 共通ライブラリの読み込み
    require_once __DIR__ . "../../../lib/sample_common.php";

    $filename = basename(__FILE__);
 
    // 共通HTMLヘッダ出力処理
    common_html_header($filename);
 
    echo "ファイル名:${filename}<br>\n";
    echo "テーブルの登録1-1・結果出力画面<br>\n";

    // POSTデータの取得
    $code = $_POST["code"];                  // 商品コード
    $name = $_POST["name"];                  // 商品名
    $goods_class = $_POST["goods_class"];    // 商品分類コード
    $price = $_POST["price"];                // 価格
    $sdate = $_POST["sdate"];                // 開始日
    $edate = $_POST["edate"];                // 終了日

    $dbn = "mysql:dbname=sampledb;host=localhost;port=3306";    // DB接続文字列
    $usr = "sampleusr";                                         // DBユーザ名
    $pw = "sample";                                             // DBユーザのパスワード

    $pdo = null;        // PDOオブジェクト

    try {
        // DB接続
        $pdo = connect_db($dbn, $usr, $pw);

        // INSERT文(商品テーブル)の生成
        $sql = "INSERT INTO GOODS VALUE(" . $pdo->quote($code) . ",";
        $sql = $sql . $pdo->quote($edate) . ",";
        $sql = $sql . $pdo->quote($name) . ",";
        $sql = $sql . $pdo->quote($sdate) . ",";
        $sql = $sql . $pdo->quote($price) . ")";

        // トランザクションの開始
        $pdo->beginTransaction();

        // INSERT文の出力、INSERT文の実行
        echo "GOODS INSERT SQL:" . $sql . ":<br>\n";
        $count = $pdo->exec($sql);
        echo "GOODSの登録件数:" . $count . ":<br>\n";

        // INSERT文(商品分類関連テーブル)の生成
        $sql2 = "INSERT INTO GOODS_CLASSES_RELARATION ";
        $sql2 = $sql2 . "VALUE(" . $pdo->quote($code) . ",";
        $sql2 = $sql2 . $pdo->quote($goods_class) . ")";

        // INSERT文の出力、INSERT文の実行
        echo "GOODS_CLASSES_RELARATION INSERT SQL:" . $sql2 . ":<br>\n";
        $count = $pdo->exec($sql2);
        echo "GOODS_CLASSES_RELARATIONの登録件数:" . $count . ":<br>\n";

        // コミット
        $pdo->commit();
    } catch(PDOException $e) {
        // エラーの出力
        echo $e->getLine() . " " . $e->getCode() . " " . $e->getMessage() . "<br>\n";
        // ロールバック
        $pdo->rollBack();
    } finally {
        // DB接続のクローズ
        if(!is_null($pdo)) {
            $pdo = null;
        }
    }
    
    // 共通HTMLフッター出力処理
    common_html_footer();
?>

・実行結果
「HeidiSQL」で登録処理後のデータベースを確認した結果は次の通りです。

「HeidiSQL」 について詳しいことを知りたい方は次の記事を見てください。

プリペアドステートメントを使用するサンプルプログラム

プリペアドステートメントを使用するサンプルプログラムです。

・画面

・入力画面のコード
入力画面のコードはプリペアドステートメントを使用しない場合と同じです。

・登録結果画面②のコード
登録結果画面②のコードです。

コメント