前ページで見た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>
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();
ファイル先頭のデータベース接続を行うまでのコードは、例外処理の構造も含めて、前ページで見たindex.phpファイルと同様だ(こちらではデータベースハンドルの属性設定にsetAttributeメソッドを使っている)。ただし、ここでは「isset関数」を使って、$_POST配列に「submit」をキーとする要素があるか(POSTメソッドでリクエストされたかどうか)を確認し、その場合にのみデータを追加するコードを実行するようにしている。実際にToDoアイテムとして入力されたデータは、<input>要素のname属性に指定した値を用いて「$_POST["item"]」のようにすることで取得可能だ(ここでは、ユーザーからの入力に対してhtmlspecialchars関数でエスケープを行わずに、index.phpファイルで表示するときにだけエスケープするようにしている)。
ここでデータの追加には、プリペアドステートメントを使い、HTMLフォームから送信されたデータをバインドするようにしている。具体的には次の手順を実行する。
上のコードではこの手順でデータを追加しているが、以下のようなコードも記述可能だ。
<?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();
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();
実際にToDoアイテムを登録している様子を以下に示す。
今回はPDOを使い、SQL Serverに対するデータの追加と取得を行った。次回は、更新と削除をPDOを使って行う予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.