レッスン6: データベースへの新しいウィッシュの追加

This tutorial needs a review. You can open a JIRA issue, or edit it in GitHub following these contribution guidelines.

このレッスンでは、次の2つの機能を使用してアプリケーションの機能を拡張します。

この機能を実装するには、 editWishList.php ファイルを編集し、新しいファイル editWish.php を作成します。

page flow diagram l6

現在のドキュメントは、PHP向けのNetBeans IDEでのCRUDアプリケーションの作成というチュートリアルの一部です。

前のレッスンからのアプリケーション・ソース・コード

MySQLユーザー: 前のレッスンが完了した後のプロジェクトの状態を反映したソース・コードをダウンロードするには、ここをクリックします。

Oracleデータベース・ユーザー: 前のレッスンが完了した後のプロジェクトの状態を反映したソース・コードをダウンロードするには、ここをクリックします。

新規ウィッシュの送信

ユーザーは、次の手順で新しいウィッシュを送信します。

  1. ユーザーは、ログインして editWishList.php ページに切り替え、「Add Wish」ボタンを押します。 editWish.php ページが開き、HTMLフォームが表示されます。

  2. HTMLフォームで、ユーザーはウィッシュの説明と、必要に応じてウィッシュが必要な期日を入力し、「Save Changes」ボタンをクリックします。

  3. ウィッシュの説明を入力せずにフォームを送信すると、ユーザーはもう一度実行するようにフォームに戻されます。ユーザーが説明なしで期日を送信した場合、その日付はフォームが再ロードされるときに再表示されます。

ユーザーがこの手順を実行できるようにするには、アプリケーションに次の機能を追加します。

ユーザー・インタフェース・コンポーネントの追加

新規ウィッシュを追加するための機能を追加するには:

  1. 「Add Wish」ボタンを実装します。 editWishList.php ファイルで、次のHTMLコードをPHPブロックの下に追加します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>

       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <form name="addNewWish" action="editWish.php">
            <input type="submit" value="Add Wish">
        </form>
    </body>
</html>

注意: HTMLバリデータからの警告は無視できます。

フォームには、 submit 型の「Add Wish」入力フィールドが含まれています。このフィールドは「Add Wish」ボタンを実装します。ユーザーが「Add Wish」をクリックすると、 editWish.php ページにリダイレクトされます。データはこのフォームを介して転送されないため、サーバー・リクエスト・メソッドは使用されません。

  1. ウィッシャの既存のウィッシュを表示する表をaddNewWishフォームの上に追加します。コードは wishlist.php と似ています。

MySQLデータベースの場合:

<table border="black">
    <tr>
        <th>Item</th>
        <th>Due Date</th>
    </tr>
    <?php
    $result = WishDB::getInstance()->get_wishes_by_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);
    ?>
</table>

Oracleデータベースの場合:

<table border="black">
    <tr><th>Item</th><th>Due Date</th></tr>
    <?php
    require_once("Includes/db.php");
    $wisherID = WishDB::getInstance()->get_wisher_id_by_name($_SESSION["user"]);
    $stid = WishDB::getInstance()->get_wishes_by_wisher_id($wisherID);
    while ($row = oci_fetch_array($stid)) {echo "<tr><td>" . htmlentities($row['DESCRIPTION']) . "</td>";echo "<td>" . htmlentities($row['DUE_DATE']) . "</td></tr>\n";
    }
    ?>
</table>
  1. 「ソース・ファイル」フォルダで editWish.php PHPファイルを作成します。

  2. editWish.php でAdd Wishフォームを実装します。次のコードを<?php?>ブロックの下に入力するか、または貼り付けます。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <form name="editWish" action="editWish.php" method="POST">
            Describe your wish: <input type="text" name="wish"  value="" /><br/>
            When do you want to get it? <input type="text" name="dueDate" value=""/><br/>
            <input type="submit" name="saveWish" value="Save Changes"/>
            <input type="submit" name="back" value="Back to the List"/>
        </form>
    </body>
</html>

Add Wishフォームには、次が含まれています。

  • ウィッシュの説明と期日を入力するための、2つの空のテキスト・フィールド。

  • 入力フィールドの横に出力されるテキスト。

  • 「Save Changes」ボタンを表す submit フィールド。

  • editWishList.php ページに戻るための「Back to the List」ボタンを表す submit フィールド。

「Add Wish」ボタンを押すと、フォームはリクエスト・メソッドPOSTを介して、入力したデータを同じ editWish.php ページに送信します。

送信に失敗した後の期日の再表示

ユーザーがAdd Wishフォームに説明を入力しなかった場合、エラー・メッセージが表示され、ユーザーは editWish.php ページに戻ります。ユーザーが editWish.php に戻ると、 dueDate を入力していた場合はAdd Wishフォームにその値が表示されます。現在のフォームの実装では、両方のフィールドは常に空です。入力した値を保持するには、新しいウィッシュのデータを配列に保存する必要があります。配列は descriptiondue_date という名前の2つの要素で構成されます。配列から dueDate フィールドの値を取得するように、Add Wishフォームを変更する必要があります。

注意: 説明が入力されていない場合に入力フォームを再ロードするコードは、データを検証してデータベースに入力するコードに含まれています。このコードについては、この項では説明しません。この項のコードは、フォームが再ロードされた場合に dueDate の値が表示されるように、その値を保持するのみです。

ユーザーが入力フォームの送信に失敗した場合に入力フォームを再表示するには:

  1. 次のコード・ブロックを、 editWish.php のHTML <body>要素内で、入力フォームの直前に入力するか、または貼り付けます。

<?php
if ($_SERVER['REQUEST_METHOD'] == "POST")
    $wish = array("description" => $_POST['wish'],
                        "due_date" => $_POST['dueDate']);
else
    $wish = array("description" => "",
                        "due_date" => "");
?>

このコードは、データの転送にどのサーバー・リクエスト・メソッドが使用されたかを確認し、$wishという名前の配列を作成します。メソッドがPOSTの場合、つまり説明が空の状態でウィッシュを保存しようとして失敗した後に入力フォームが表示される場合、 descriptiondue_date の要素はPOSTを介して転送された値を受け取ります。

メソッドがPOSTでない場合、つまり editWishList.php ページからのリダイレクト後に初めて入力フォームが表示される場合、 descriptiondue_date の要素は空です。

注意: どちらの場合も説明は空です。 dueDate が異なるのみです。

  1. Add Wishフォームの入力フィールドの値が $wish 配列から取得されるように、Add Wishフォームを更新します。Add Wishフォームの次の行が対象です。

Describe your wish: <input type="text" name="wish"  value="" /><br/>
When do you want to get it? <input type="text" name="dueDate" value=""/><br/>

次と置き換えます。

Describe your wish: <input type="text" name="wish"  value="<?php echo $wish['description'];?>" /><br/>
When do you want to get it? <input type="text" name="dueDate" value="<?php echo $wish['due_date']; ?>"/><br/>

ウィッシャのログオンの確認

`editWish.php` ファイルで、ファイルの先頭の<? >ブロック内に次のセッション処理コードを入力します。
session_start();
if (!array_key_exists("user", $_SESSION)) {
    header('Location: index.php');
    exit;
}

このコードは次を実行します。

  • データを取得するために$_SESSION配列を開く。

  • 配列$_SESSIONに、識別子が「user」の要素が含まれていることを確認する。

  • 確認に失敗した場合、つまりユーザーがログオンしていない場合、最初のindex.phpページにアプリケーションがリダイレクトされ、PHPの処理が取り消される。

セッション処理が正しく動作していることを確認するには、IDEからeditWish.phpファイルを実行します。セッションを介してeditWish.pageページにユーザーが転送されていないため、index.phpページが開きます。

データベースへの新しいウィッシュの挿入

ユーザーが新しいウィッシュを送信した後、アプリケーションはそのウィッシュを「wishes」データベースに追加する必要があります。この機能を有効にするには、次のコードをアプリケーションに追加します。

  • db.phpWishDB クラスに、補助関数をさらに2つ追加する。

  • 1つの関数は、wishes表に新しいレコードを追加します。

  • もう1つの関数は、日付をMySQLデータベース・サーバーがサポートする形式に変換します。

  • WishDB の新しい補助関数を使用してデータベースに新しいウィッシュを入力するコードを、 editWish.php に追加する。

WishDBへのinsert_wish関数の追加

この関数は、入力パラメータとして、ウィッシャのID、新しいウィッシュの説明、およびそのウィッシュの期日を必要とし、このデータをデータベースの新規レコードに入力します。この関数は値を返しません。

`db.php` を開き、関数 `insert_wish` を `WishDB` クラスに追加します。

MySQLデータベースの場合

function insert_wish($wisherID, $description, $duedate) {
    $description = $this->real_escape_string($description);
    if ($this->format_date_for_sql($duedate)==null){
       $this->query("INSERT INTO wishes (wisher_id, description)" .
            " VALUES (" . $wisherID . ", '" . $description . "')");
    } else
        $this->query("INSERT INTO wishes (wisher_id, description, due_date)" .
            " VALUES (" . $wisherID . ", '" . $description . "', "
            . $this->format_date_for_sql($duedate) . ")");
}

Oracleデータベースの場合:

function insert_wish($wisherID, $description, $duedate) {
    $query = "INSERT INTO wishes (wisher_id, description, due_date) VALUES (:wisher_id_bv, :desc_bv, to_date(:due_date_bv, 'YYYY-MM-DD'))";
    $stid = oci_parse($this->con, $query);
    oci_bind_by_name($stid, ':wisher_id_bv', $wisherID);
    oci_bind_by_name($stid, ':desc_bv', $description);
    oci_bind_by_name($stid, ':due_date_bv', $this->format_date_for_sql($duedate));
    oci_execute($stid);
    oci_free_statement($stid);
}

このコードは関数format_date_for_sqlをコールし、入力した期日をデータベース・サーバーが処理できる形式に変換します。次に、問合せINSERT INTO wishes (wisher_id, description, due_date)を実行し、新しいウィッシュをデータベースに入力します。

WishDBへのformat_date_for_sql関数の追加

関数 format_date_for_sqldb.php 内の WishDB クラスに追加します。この関数は、入力パラメータとして日付の入った文字列を必要とします。この関数は、データベース・サーバーが処理できる形式で日付を返すか、または入力文字列が空の場合は null を返します。

注意: この例の関数は、PHP date_parse 関数を使用します。この関数は、「December 25, 2010」などの英語の日付でのみ機能し、アラビア数字専用です。高度なWebサイトでは日付ピッカーを使用します。

MySQLデータベースの場合:

function format_date_for_sql($date) {
    if ($date == "")
        return null;
    else {
        $dateParts = date_parse($date);
        return $dateParts["year"] * 10000 + $dateParts["month"] * 100 + $dateParts["day"];
    }
}

Oracleデータベースの場合:

function format_date_for_sql($date) {
    if ($date == "")
        return null;
    else {
        $dateParts = date_parse($date);
        return $dateParts['year'] * 10000 + '-' + $dateParts['month'] * 100 + '-' + $dateParts['day'];
    }
}

入力文字列が空の場合、このコードはNULLを返します。それ以外の場合は、入力パラメータとして $date を使用する内部の date_parse 関数がコールされます。 date_parse 関数は、 $dateParts["year"]$dateParts["month"] 、および $dateParts["day"] の3つの要素から構成される配列を返します。最終的な出力文字列は、 $dateParts 配列の要素で構成されます。

重要: date_parse 関数は英語の日付のみ認識します。たとえば、「February 2, 2016」は解析しますが、「2 Unora, 2016」は解析しません。

Oracleデータベース・ユーザーへの注意: 形式の要件は、 return$dateParts…​ 文の日付の形式が、 insert_wish 問合せの to_date SQL関数の日付形式と一致することのみです。

データベースへの新規ウィッシュ・レコードの入力

補助関数の開発が完了したので、新規ウィッシュ・データを検証するコードを追加し、データが有効である場合は、そのデータをデータベースに入力します。データが有効でない場合、コードはAdd Wishフォームを再ロードする必要があります。期日が入力されているが説明が入力されていないためにデータが無効な場合、フォームが再ロードされるときに、以前に開発したコードによって期日が保存され、再表示されます。

次のコードを、先頭の<?php?>ブロック( editWish.php 内)のセッション処理コードの下に入力します。

require_once("Includes/db.php");
$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_SESSION['user']);

$wishDescriptionIsEmpty = false;
if ($_SERVER['REQUEST_METHOD'] == "POST"){
    if (array_key_exists("back", $_POST)) {
        header('Location: editWishList.php' );
        exit;
    } else
    if ($_POST['wish'] == "") {
        $wishDescriptionIsEmpty =  true;
    } else {
        WishDB::getInstance()->insert_wish($wisherID, $_POST['wish'], $_POST['dueDate']);
        header('Location: editWishList.php' );
        exit;
    }
}

このコードは次の関数を実行します。

  • db.php ファイルの使用を有効にする。

  • クラス WishDB のインスタンスを取得または作成する。

  • 関数 get_wisher_id_by_name をコールして、ウィッシュを追加しようとしているウィッシャのIDを取得する。

  • $wishDescriptionIsEmpty フラグを初期化する(これは、後でエラー・メッセージの表示に使用されます)。

  • リクエスト・メソッドがPOSTであることを確認する(これは、このデータが editWish.php ページ自身のウィッシュ・データを入力するためのフォームから送信されたことを意味します)。

  • $_POST 配列が「back」キーを持つ要素を含んでいるかどうかを確認する。

    `$_POST` 配列が「back」キーを持つ要素を含んでいる場合、フォームを送信する前に「Back to the List」ボタンが押されます。この場合、コードは、フィールドに入力されたデータを保存せずにユーザーを `editWishList.php` にリダイレクトし、PHP処理を停止します。

$_POST配列が「back」キーを持つ要素を含んで_いない_場合、データは「Save Changes」ボタンを押すことによって送信されます。この場合、コードは、ウィッシュの説明が入力されているかどうかを検証します。コードは、$_POST配列内の「wish」キー持つ要素が空であるかどうかを確認し、キーが空の場合は$wishDescriptionIsEmptyフラグをtrueに変更します。PHPブロックのコードがさらに実行されることはなく、Add Wishフォームが再ロードされます。

「Back to the List」ボタンが押されず、ウィッシュの説明が入力されている場合、コードは入力パラメータとしてウィッシャのID、ウィッシュの説明、およびウィッシュの期日を持つ関数 insert_wish をコールします。コードはユーザーを editWishList.php ページにリダイレクトし、PHP処理を停止します。

エラー・メッセージの表示

ユーザーがウィッシュの説明を入力せずにウィッシュを保存しようとした場合、エラー・メッセージが表示されます。 次の<?php?>ブロックを、HTML入力フォーム内の「Describe your wish」入力フィールドの下に入力します。

<?php
if ($wishDescriptionIsEmpty)
    echo "Please enter description<br/>";
?>
`$wishDescriptionIsEmpty` フラグがtrueの場合は、エラー・メッセージが表示されます。フラグは、入力フォームの検証時に処理されます。

最初のindex.phpページへの復帰

ボタンを押すことによって、ユーザーがいつでもアプリケーションの最初のページに戻ることができるようにします。 この機能を実装するには、次のHTML入力フォームを editWishList.php ファイルの終了</body>タグの前に入力します。

<form name="backToMainPage" action="index.php"><input type="submit" value="Back To Main Page"/></form>

「Back to Main Page」ボタンを押すと、フォームは、ユーザーを最初のindex.phpページにリダイレクトします。

ウィッシュの追加機能のテスト

  1. アプリケーションを実行します。 index.php ページで、「Username」フィールドに「Tom」、「Password」フィールドに「tomcat」と入力します。

user logon to edit wish list
  1. 「Edit My Wish List」ボタンを押します。 editWishList.php ページが開きます。

edit wish list add wish
  1. 「Back to Main Page」ボタンを押します。 index.php ページが開きます。

  2. 「Tom」としてログオンし、もう一度「Edit My Wish List」ボタンを押します。 editWishList.php ページが開きます。

  3. 「Add Wish」ボタンを押します。 editWish.php ページが開きます。フォームに入力します。

new wish

「Back to the List」ボタンを押します。 editWishList.php ページが開きますが、入力したウィッシュは追加されていません。

  1. 再度「Add Wish」ボタンを押します。 editWish.php ページが開きます。期日を入力し、説明を空のままにします。「Save Changes」ボタンを押します。 editWish.php ページには、エラー・メッセージが表示され、期日が入力されている状態の入力フォームが表示されます。

  2. 再度「Add Wish」ボタンを押します。 editWish.php ページが開きます。フォームに入力し、「Save Changes」ボタンを押します。 editWishList.php ページに更新されたウィッシュのリストが表示されます。

edit wish list updated

現在のレッスン完了後のアプリケーション・ソース・コード

MySQLユーザー: このレッスンが完了した後のプロジェクトの状態を反映したソース・コードをダウンロードするには、ここをクリックします。

Oracleデータベース・ユーザー: このレッスンが完了した後のプロジェクトの状態を反映したソース・コードをダウンロードするには、ここをクリックします。

次の手順

users@php.netbeans.orgメーリング・リストに登録することによって、NetBeans IDE PHP開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。