連載
» 2018年10月30日 05時00分 公開

.NET開発者のためのPHPアプリお手軽開発入門:VS CodeとPHPとSQL Serverで作るToDoリストアプリ (2/2)

[かわさきしんじ,Insider.NET編集部]
前のページへ 1|2       

PDOを利用したデータベースへのデータ追加

 前ページで見たindex.phpファイルのHTML部分では次のようにしてHTMLフォームを作成し、[送信]ボタンがクリックされたら、additem.phpファイルが実行されるようにしてある。

<p>register todo item</p>
<form action="additem.php" method="post">
  item: 
  <input name="item">
  <input type="submit" name="submit">
</form>

ToDoアイテムを登録するためのHTMLフォーム

 PHPでは、POSTメソッドにより送信されたデータは定義済みの変数$_POSTに連想配列の形で保存される。そのため、PHPコードでは、これを参照してデータを受け取り、それをデータベースに追加する。実際のコードは次のようになる。

<?php
if (isset($_POST["submit"])) {
  try {
    $serverName = "(localDB)\\vscphpwebapps";
    $uid = "sa";
    $pwd = "**********";
    $dbname = "todolist";
    $dsn = "sqlsrv:server=" . $serverName . ";database=" . $dbname;

    $pdo = new PDO($dsn, $uid, $pwd);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $tsql = "INSERT INTO todoitems (item, done) VALUES (?, 0)";
    $stmt = $pdo->prepare($tsql);

    $item = $_POST["item"];
    $stmt->bindValue(1, $item, PDO::PARAM_STR);

    $stmt->execute();
  } catch (Exception $e) {
    header("Content-Type: text/plain; charset=UTF-8", true, 500);
    exit();
  } finally {
    $stmt = null;
    $pdo = null;
  }
}
header("Location: index.php");
exit();


PDOを利用したデータベースへのデータ追加(additem.phpファイル)

 ファイル先頭のデータベース接続を行うまでのコードは、例外処理の構造も含めて、前ページで見たindex.phpファイルと同様だ(こちらではデータベースハンドルの属性設定にsetAttributeメソッドを使っている)。ただし、ここでは「isset関数」を使って、$_POST配列に「submit」をキーとする要素があるか(POSTメソッドでリクエストされたかどうか)を確認し、その場合にのみデータを追加するコードを実行するようにしている。実際にToDoアイテムとして入力されたデータは、<input>要素のname属性に指定した値を用いて「$_POST["item"]」のようにすることで取得可能だ(ここでは、ユーザーからの入力に対してhtmlspecialchars関数でエスケープを行わずに、index.phpファイルで表示するときにだけエスケープするようにしている)。

 ここでデータの追加には、プリペアドステートメントを使い、HTMLフォームから送信されたデータをバインドするようにしている。具体的には次の手順を実行する。

  1. PDOオブジェクトのprepareメソッドに実行したいSQLのひな型を渡して、プリペアドステートメント(PDOStatementオブジェクト)を作成する
  2. PDOStatementオブジェクトのbindValueメソッドで、プリペアドステートメントに含まれるパラメーターマーク(上のコードでは「?」がパラメーターマーク)と、$_POST["item"]の値とをバインドする。このとき、上のコードではデータ型として「PDO::PARAM_STR」としてこれが文字列型であることを指定している
  3. PDOStatementオブジェクトのexecuteメソッドを呼び出す

 上のコードではこの手順でデータを追加しているが、以下のようなコードも記述可能だ。

<?php
if (isset($_POST["submit"])) {
  try {
    // …… 省略 ……
    $tsql = "INSERT INTO todoitems (item, done) VALUES (:item, 0)";
    $stmt = $pdo->prepare($tsql);

    $item = $_POST["item"];
    $stmt->bindValue(":item", $item, PDO::PARAM_STR);

    $stmt->execute();
  } catch (Exception $e) {
    // …… 省略 ……
  } finally {
    // …… 省略 ……
  }
}
// …… 省略 ……


名前付きのパラメーターマークを使用する例

 最初のコードではパラメーターマークに「?」を使用していたが、上のコードでは「:item」がパラメーターマークとして使われている。PHPではこのように2種類のパラメーターマークがサポートされており、bindValueメソッドではインデックス番号もしくはパラメーターマークの名前を指定して、実際のSQL実行で使用するデータをバインドできるようになっている。

 例外発生時の処理は前ページと同様だ。ただし、finallyブロックでこのファイルの実行で作成したリソースを削除するようになっている。

 最後に$_POST変数に"submit"をキーとする値があるかどうかに関係なく(このファイルが「http://localhost:3000/additem.php」などのようにリクエストされたか、[送信]ボタンのクリックにより、データが追加されたかに関係なく)、index.phpファイルにリダイレクトするようにしている。

<?php
if (isset($_POST["submit"])) {
  // …… 省略 ……
}
header("Location: index.php");
exit();


最終的にindex.phpページを表示

 header関数を利用して、リダイレクトを行う際には幾つか注意点がある。まず、header関数のドキュメントには「header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要がある」と書いてあることだ。詳細な議論については前掲のリンクを参照のこと。

 次に、上では相対URIをLocationヘッダに指定しているが、古いブラウザではこれが問題となる場合があることだ。絶対URIを作成する手順についても前掲のリンクを参照されたい。上のコードなら次のようになる。

<html>
<?php
if (isset($_POST["submit"])) {
  // …… 省略 ……
}
$host = $_SERVER["HTTP_HOST"];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = "index.php";
header("Location: http://$host$uri/$extra");
exit();


絶対URIによるリダイレクト

 実際にToDoアイテムを登録している様子を以下に示す。

ToDoアイテムを登録しているところ ToDoアイテムを登録しているところ


 今回はPDOを使い、SQL Serverに対するデータの追加と取得を行った。次回は、更新と削除をPDOを使って行う予定だ。

「.NET開発者のためのPHPアプリお手軽開発入門」のインデックス

.NET開発者のためのPHPアプリお手軽開発入門

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。