PHP を使用するデータベース駆動型アプリケーションの作成
レッスン 2: アプリケーションの設計。データベースからの読み取り
このレッスンでは、アプリケーションを開発するために PHP プロジェクトを作成および構成し、アプリケーション内のページのリストを作成して、それらの関係を定義します。また、基本的なアプリケーションの機能を開発し、レッスン 1 のサンプルデータベースに入力したデータに対してテストします。
このレッスンで記述する PHP コードは次の機能を実行します。
1. ユーザーが入力した個人の名前を取得します。
2. その個人が実際にデータベース内に存在するか確認します。個人がデータベースに存在しない場合はエラーメッセージで終了します。
3. その個人のウィッシュ表を表示します。
現在のドキュメントは、チュートリアル「NetBeans IDE for PHP でのデータベース駆動型アプリケーションの作成」の一部です。
PHP プロジェクトの作成
「ファイル」>「新規プロジェクト」(Windows および Linux では Ctrl-Shift-N、MacOS では ⌘-Shift-N) を選択します。「wishlist」という名前の新しい PHP プロジェクトを作成します。PHP プロジェクトを作成すると、PHP プロジェクトはデフォルトでインデックスファイル index.php を含みます。PHP プロジェクトの作成と構成については、「PHP プロジェクトの設定 」を参照してください。
ページフロー図の定義
アプリケーションのスコープは、次のユースケースをカバーしています。
ユーザーが、個人のウィッシュリストを表示する。
ユーザーを新規ウィッシャーとして登録する。
ユーザーがログインして自分のウィッシュリストを作成する。
ユーザーがログインして自分のウィッシュリストを編集する。
この基本的な機能をカバーするためには、次の PHP ファイルを実装する必要があります。
ログイン、登録、およびほかのユーザーのウィッシュリストに切り替えるための「フロント」ページである index.php。
特定のウィッシャーのウィッシュリストを表示するための wishlist.php ページ。
ウィッシャーとして登録するための createNewWisher.php ページ。
所有者がウィッシュリストを編集するための editWishList.php ページ。
ウィッシュを作成して編集するための editWish.php ページ。
準備手順が完了したので、アプリケーションの基本的な機能の実装を開始できます。ウィッシャーのウィッシュリストの表示から始めます。この機能には検査が含まれていないので、テストデータをデータベースにすでに入力したように、簡単にテストすることができます。この機能は、index.php と wishlist.php の 2 つのページに実装されます。
index.php へのフォームの追加
index.php ファイルには PHP コードが含まれていないため、簡単に次のブロックを削除できます。
index.php ファイルは 2 つの目的で使用されます。
データ入力の制御があるページを表示する。
入力されたデータを、データが処理される別の PHP ファイルに転送する。このチュートリアルでは、データは次の節で作成およびコーディングする wishlist.php という名前のファイルに渡されます。
これらのアクションは HTML フォームを使用して実行されます。それぞれの HTML フォームには次が含まれています。
ページ上の制御に対応するフィールドのセット。
ユーザーがフォームのデータを送信したあとに実行される「アクション」。アクションは、データを処理するページへのパスによって表現されます。
index.php にフォームを追加するには、次を実行します。
「プロジェクト」ウィンドウに切り替え、プロジェクトノードおよび「ソースファイル」ノードを展開し、index.php ファイルをダブルクリックします。index.php ファイルがメインの IDE 編集領域で開きます。ファイルには、HTML および PHP コードを入力するためのテンプレートが含まれています。
注: HTML バリデータからの警告は無視できます。
PHP ブロックを削除します。index.php ファイルには PHP コードが含まれていません。
<head> 要素の内部に次の要素が存在しない場合、要素を挿入します。この要素によって、フォームで UTF-8 国際文字が使用できるようになります。 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
「ウィンドウ」メニューから、または Ctrl-Shift-8 キーを押して「パレット」を開きます。
パレットの「HTML フォーム 」セクションで、「フォーム」を index.php の <body> セクションにドラッグ&ドロップします。
「挿入フォーム」ダイアログが開きます。「アクション」フィールドで、フォームによるデータの転送先のファイルへのパスを入力します。今回のケースでは、wishlist.php と入力します。(このファイルは index.php と同じ場所に作成します。「wishlist.php の作成とアプリケーションのテスト 」を参照してください。) データを転送するための GET メソッドを選択します。フォームに対して wishList などの任意の名前を付けます。完了したら、「了解」をクリックします。
ファイルは次のようになっています。
フォームの開始タグと終了タグの間に、「Show wish list of: 」というテキストを入力します。
パレットの「HTML フォーム 」セクションから、「テキスト入力」コンポーネントを「Show wish list of: 」のあとのスペースにドラッグします。「挿入テキスト入力」ダイアログが開きます。
入力に user という名前を付けます。入力の種類は「テキスト 」を選択します。その他のすべてのフィールドを空白のままにし、「了解」をクリックします。
ファイルは次のようになっています。
</form> タグの上に空白行を追加します。この空白行に、パレットの「HTML フォーム 」セクションから「ボタン」コンポーネントをドラッグ&ドロップします。
「挿入ボタン」ダイアログが開きます。「ラベル」フィールドに「Go 」と入力して「了解」をクリックします。
フォームは今度は次のようなコードになり、違いは 1 つです。次のコードでは、<form> タグ内の method 属性が明示的になっています。NetBeans IDE はメソッド属性をフォームに追加しませんでしたが、この理由は GET がこの属性のデフォルト値であるためです。ただし、method 属性が明示的であれば、コードが理解しやすくなる場合があります。
<form action="wishlist.php" method="GET" name="wishList"> Show wish list of: <input type="text" name="user" value=""/> <input type="submit" value="Go" /> </form>
フォームの次の要素に注意してください。
開始の <form> タグには action 属性が含まれています。action 属性は、フォームがデータを転送するファイルを指定します。今回のケースでは、ファイルの名前は wishlist.php で、index.php と同じフォルダに存在します。(このファイルは「wishlist.php の作成とアプリケーションのテスト 」の節で作成します。)
開始の <form> タグには、データの転送に適用されるメソッド (GET) も含まれています。PHP は method 属性の値に応じて、このフォームによって渡される値について $_GET または $_POST 配列を使用します。今回のケースでは、PHP は $_GET を使用します。
text 入力コンポーネント。このコンポーネントは、表示するウィッシュリストのユーザー名を入力するためのテキストフィールドです。テキストフィールドの開始値は、空の文字列です。このフィールドの名前は user です。PHP はフィールドの値の配列を作成するとき、フィールドの名前を使用します。今回のケースでは、このフィールドの値の配列は htmlentities($_GET["user"]) です。
「Go」の値を持つ submit 入力コンポーネント。「submit」タイプは、入力フィールドがボタンとしてページに表示されることを意味します。値「Go」はボタンのラベルです。ユーザーがボタンをクリックすると、text コンポーネント内のデータは action 属性で指定されるファイルに転送されます。
wishlist.php の作成とアプリケーションのテスト
「index.php へのフォームの追加 」では、ユーザーが表示するウィッシュリストの所有者の名前をユーザーが送信するフォームを作成しました。名前は wishlist.php ページに渡されます。ただし、このページは存在しません。index.php を実行すると、名前を送信したときに「404: File Not Found」エラーを受け取ります。この節では、wishlist.php を作成し、アプリケーションをテストします。
wishlist.php を作成してアプリケーションをテストするには、次を実行します。
作成した「wishlist」プロジェクト内において、「ソースファイル」ノードでマウスの右ボタンをクリックし、コンテキストメニューから「新規」>「PHP ファイル」を選択します。「新規 PHP ファイル」ウィザードが開きます。
「ファイル名」フィールドに「wishlist 」と入力し、「完了」をクリックします。
ソースノードでマウスの右ボタンをクリックし、コンテキストメニューから「プロジェクトを実行」を選択するか、プロジェクトを主プロジェクトに設定している場合は、ツールバーの「主プロジェクトを実行」アイコン をクリックします。
「Show wish list of:」編集ボックスに「Tom」と入力し、「Go」をクリックします。URL が http://localhost:90/Lesson2/wishlist.php?user=tom の、空のページが表示されます。この URL は、メインページが正しく動作していることを示します。
接続の確立とウィッシャー ID の取得
この節では最初に、データベースへの接続を作成するコードを wishlist.php に追加します。次に、名前が index.php フォームに入力されたウィッシャーの ID 番号を取得するコードを追加します。
wishlist.php ファイルをダブルクリックします。表示されるテンプレートは、index.php とは異なります。このファイルは HTML コードも含むため、ファイルの開始と終わりに <html></html> タグおよび <body></body> タグがあります。
<html>
<body>
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
?>
</body>
</html>
タイトルを表示するには、開始の <body> タグの直後、生成された <?php タグの前に次のコードを入力します。
Wish List of <?php echo htmlentities($_GET["user"])."<br/>";?>
コードは次のようになります。
<html>
<body>Wish List of <?php echo htmlentities($_GET["user"])."<br/>";?> <?php
/* * To change this template, choose Tools | Templates
* and open the template in the editor. */
?>
</body>
</html>
PHP コードブロックは、「user」フィールドの取得メソッド (GET) を介して受け取ったデータを表示します。このデータは、テキストフィールド「user」に、ウィッシュリストの所有者である Tom の名前が入力されている index.php から転送されます。wishlist.php が正しく動作していることを確認するために、手順を「index.php のテスト 」から繰り返します。
テンプレート PHP ブロックのコメント付きセクションを削除します。その場所に、次のコードを入力またはペーストします。このコードはデータベースへの接続を開きます。
MySQL データベースの場合:
$con = mysqli_connect("localhost", "phpuser", "phpuserpw"); if (!$con) { exit('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error()); } //デフォルトのクライアント文字セットを設定する mysqli_set_charset($con, 'utf-8');
Oracle データベースの場合:
$con = oci_connect("phpuser", "phpuserpw", "localhost/XE", "AL32UTF8");
if (!$con) {
$m = oci_error();
exit('Connect Error ' . $m['message']);
}
コードはデータベースへの接続を開くことを試み、エラーがある場合はエラーメッセージを返します。
Oracle データベースユーザーへの注: oci_connect コマンド内のデータベース接続を変更することが必要な場合があります。標準の構文は「ホスト名/サービス名」です。このスニペット内での Oracle XE データベースへの接続は、この構文に従って「localhost/XE」です。
注: mysqli 関数または OCI8 関数のいずれかについて、NetBeans IDE のコード補完を使用できます。
コードの下にデータベースへの接続が開き、同じ PHP ブロックに次のコードを入力またはペーストします。このコードは、ウィッシュリストが要求されたウィッシャーの ID を取得します。ウィッシャーがデータベースに存在しない場合、コードはプロセスを終了し、エラーメッセージを表示します。
MySQL データベースの場合:
mysqli_select_db($con, "wishlist");
$user = mysqli_real_escape_string($con, htmlentities($_GET["user"]));
$wisher = mysqli_query($con, "SELECT id FROM wishers WHERE name='" . $user . "'");
if (mysqli_num_rows($wisher) < 1) {
exit("The person " . htmlentities($_GET["user"]). " is not found. Please check the spelling and try again" );
} $row = mysqli_fetch_row($wisher); $wisherID = $row[0]; mysqli_free_result($wisher);
Oracle データベースの場合: (oci8 には mysqli_num_rows と同等のものが存在しません)
$query = "SELECT id FROM wishers WHERE NAME = :user_bv";
$stid = oci_parse($con, $query);
$user = $_GET['user'];
oci_bind_by_name($stid, ':user_bv', $user);
oci_execute($stid);
//ユーザーは一意の値であるため 1 行のみが期待される
$row = oci_fetch_array($stid, OCI_ASSOC);
if (!$row) {
exit("The person " . $user . " is not found. Please check the spelling and try again" );
}
$wisherID = $row['ID'];
oci_free_statement($stid);
データは、$con 接続を介して wishlist データベースから選択されます。選択の基準は、index.php から「user」として受け取った名前です。
次に、SQL 文「SELECT 」の構文を簡単に説明します。
SELECT のあとに、データの取得元のフィールドを指定します。アスタリスク (*) はすべてのフィールドを表します。
FROM 節のあとに、データを取得する表の名前を指定します。
WHERE 節は任意です。フィルタ条件を指定します。
mysqli クエリーは結果オブジェクトを返します。OCI8 は実行された文を返します。いずれの場合も、実行されたクエリーの結果から 1 行を取得し、ID 行の値を抽出し、それを変数 $wisherID に格納します。
最後に、mysqli 結果または OCI8 文を解放します。接続が物理的に切断される前に、接続を使用するすべてのリソースを解放する必要があります。それ以外の場合、mysqli_close() 呼び出しまたは oci_close() 呼び出しのあとに $con が使用できない場合でも、PHP の内部参照カウントシステムは、ベースとなる DB 接続を開き続けます。
セキュリティー上の注意: MySQL の場合、「htmlentities($_GET["user"]) 」パラメータは、SQL インジェクション攻撃を避けるため、エスケープされます。SQL インジェクションに関する Wikipedia および mysql_real_escape_string のドキュメント を参照してください。このチュートリアルのコンテキストでは、有害な SQL インジェクションのリスクはありませんが、そのような攻撃のリスクになるような MySQL クエリーの文字列はエスケープするのがベストプラクティスです。OCI8 はバインド変数によってこれを回避します (「PHP Oracle FAQs 」を参照し、「バインド変数 (bind variable)」および「インジェクション (injection)」で検索してください)。
PHP ブロックはこれで完了です。MySQL データベースを使用している場合、wishlist.php ファイルは次のようになっています。
Wish List of <?php echo htmlentities($_GET["user"]) . "<br/>"; ?>
<?php
$con = mysqli_connect("localhost", "phpuser", "phpuserpw");
if (!$con) {
exit('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
//デフォルトのクライアント文字セットを設定する
mysqli_set_charset($con, 'utf-8');
mysqli_select_db($con, "wishlist");
$user = mysqli_real_escape_string($con, htmlentities($_GET["user"]));
$wisher = mysqli_query($con, "SELECT id FROM wishers WHERE name='" . $user . "'");
if (mysqli_num_rows($wisher) < 1) {
exit("The person " . htmlentities($_GET["user"]). " is not found. Please check the spelling and try again");
}
$row = mysqli_fetch_row($wisher);
$wisherID = $row[0];
mysqli_free_result($wisher);
?>
Oracle データベースを使用している場合、wishlist.php ファイルは次のようになっています。
Wish List of <?php echo htmlentities($_GET["user"]) . "<br/>"; ?>
<?php
$con = oci_connect("phpuser", "phpuserpw", "localhost/XE", "AL32UTF8");
if (!$con) {
$m = oci_error();
exit('Connect Error ' . $m['message'];
exit;
}
$query = "SELECT id FROM wishers WHERE name = :user_bv";
$stid = oci_parse($con, $query);
$user = htmlentities($_GET["user"]);
oci_bind_by_name($stid, ':user_bv', $user);
oci_execute($stid);
//ユーザーは一意の値であるため 1 行のみが期待される
$row = oci_fetch_array($stid, OCI_ASSOC);
if (!$row) {
exit("The person " . $user . " is not found. Please check the spelling and try again" );
}
$wisherID = $row["ID"];
oci_free_statement($stid);
?>
アプリケーションのテストで無効なユーザーを入力すると、次のメッセージが表示されます。
ウィッシュ表の表示
この節では、ウィッシャーに関連付けられたウィッシュの HTML 表を表示するコードを追加します。ウィッシャーは、前の節のコードで取得した ID によって識別されます。
PHP ブロックの下に、次の HTML コードブロックを入力またはペーストします。このコードは、表を開き、境界線の色を指定し (黒)、「Item」列および「Due Date」列を持つ表ヘッダーを「描画」します。
<table border="black">
<tr>
<th>Item</th>
<th>Due Date</th>
</tr>
</table>
</table> タグが表を閉じます。
次の PHP コードブロックを、終了 </table> タグの前に入力します。
MySQL データベースの場合:
<?php $result = mysqli_query($con, "SELECT description, due_date FROM wishes WHERE wisher_id=" . $wisherID); while ($row = mysqli_fetch_array($result)) { echo "<tr><td>" . htmlentities($row["description"]) . "</td>"; echo "<td>".htmlentities($row["due_date"]) . "</td></tr>\n"; } mysqli_free_result($result); mysqli_close($con); ?>
Oracle データベースの場合:
<?php $query = "SELECT description, due_date FROM wishes WHERE wisher_id = :id_bv"; $stid = oci_parse($con, $query); oci_bind_by_name($stid, ":id_bv", $wisherID); oci_execute($stid); while ($row = oci_fetch_array($stid)) { echo "<tr><td>" . htmlentities($row["DESCRIPTION"]) . "</td>"; echo "<td>".htmlentities($row["DUE_DATE"]) . "</td></tr>\n"; } oci_free_statement($stid); oci_close($con); ?>
コード内は次のようになっています。
SELECT クエリーは、手順 4 で取得されたウィッシャーの ID によって、指定したウィッシャーに対するウィッシュの期日とともにウィッシュを取得し、そのウィッシュと期日を配列 $result に格納します。
ループは、$result 配列が空でない間、この配列の項目を表の行として表示します。
<tr></tr> タグは行を形成し、<td></td> タグは行内のセルを形成します。また、\n は新しい行を開始します。
htmlentities 関数は、HTML エンティティーと等価な意味を持つすべての文字を、HTML エンティティーに変換します。これはクロスサイトスクリプティング の防止に役立ちます。
最後の関数はすべてのリソース (mysqli 結果および OCI8 文) を解放し、データベース接続を閉じます。接続が物理的に切断できるようになる前に、接続を使用するすべてのリソースを解放する必要があります。それ以外の場合、oci_close() 呼び出しまたは mysqli_close() 呼び出しのあとに接続が使用できない場合でも、PHP の内部参照カウントシステムは、ベースとなる DB 接続を開き続けます。
注意: データベース表の作成時に指定したとおりに、データベースフィールドの名前が入力されていることを確認してください。Oracle の場合、列名はデフォルトで大文字で返されます。
アプリケーションをテストするには、「index.php のテスト 」の節の説明に従ってプロジェクトを実行します。
現在のレッスン完了後のアプリケーションソースコード
MySQL ユーザー: このレッスンが完了したあとのプロジェクトの状態を反映したソースコードをダウンロードするには、ここ をクリックします。
Oracle データベースユーザー: このレッスンが完了したあとのプロジェクトの状態を反映したソースコードをダウンロードするには、ここ をクリックします。
次の手順
<< 前のレッスン
次のレッスン >>
チュートリアルのメインページに戻る
便利なリンク
HTML、PHP、および MySQL または Oracle データベースの使用については、次を参照してください。
users
@
php.netbeans.org
メーリングリストに登録する ことによって、NetBeans IDE PHP 開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。
PHP の学習に戻る