レッスン7: データベース内のエントリの更新および削除

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 ファイルを編集します。また、 deleteWish.php という名前の新しいファイルも作成します。

page flow diagram l7

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

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

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

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

ウィッシュの編集

この機能は、次のユース・ケースをサポートしています。

  • editWishList.php ページで、ユーザーがウィッシュの右にある「Edit」ボタンを押す。選択したウィッシュのデータがある editWish.php ページが開く。

  • ユーザーがウィッシュの説明または期日(あるいはその両方)を変更し、「Save Changes」ボタンを押す。

  • 説明が入力されて_いない_場合、エラー・メッセージが表示され、ユーザーが editWish.php ページに戻される。

  • 説明が入力されている場合、アプリケーションはウィッシュが更新される editWishList.php ページに戻る。

この実装は、次の手順から構成されます。

「Edit」ボタンの実装

`editWishList.php` では、ウィッシャのウィッシュを含む表は、ウィッシュがデータベースから選択されるときに、ウィッシュを含む行を表示するループ( `while` 文)によって実装されています。行の一番右のセルとして「Edit」ボタンを追加します。
  1. HTML入力フォームを使用してウィッシュのIDを転送するには、そのIDを変数に格納します。次のコード行を while ループの末尾に入力します。

while ($row = mysqli_fetch_array($result)):
    echo "<tr><td>" . htmlentities($row['description']) . "</td>";
    echo "<td>" . htmlentities($row['due_date']) . "</td>";
    $wishID = $row['id'];
    echo "<td>WishID=" . $wishID . "</td>";
    //The loop is left open
    ?>
  1. 編集ボタンを実装します。editWishフォームを使用して、終了の</table>タグの前に別の表のセルを追加します。このフォームには、ボタン・コンポーネントと、ボタンがクリックされたときに $wishID の値を送信する非表示コンポーネントが含まれています。(MySQLデータベース用のコードが示されていますが、追加されるコードはOracleデータベースの場合も同じで、同じ場所になります。)

Hello <?php echo $_SESSION["user"]; ?><br/>
<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"]);
    $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);
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>">
            <input type="submit" name="editWish" value="Edit">
        </form>
    </td>
</table>
  1. while ループを変更して代替構文を使用します。これにより、 while ループ内のHTMLブロックを実行しやすくなります。代替の while ループ構文では、開始の中括弧{がコロン(:)に置き換えられ、終了の中括弧}が endwhile; 文に置き換えられます。開始の中括弧をコロンに置き換え、終了の中括弧を削除し、 endwhile; 文を使用して終了の</table>タグの前に新しいPHPブロックを追加します。これにより、新しい表のセルが while ループに組み込まれます。結果または文を解放するコードを endwhile; 文の後に移動します。(ここでも、MySQL用のコードが示されていますが、コード変更および場所はOracleデータベースの場合も同じです。)

   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);
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
           <input type="hidden" name="wishID" value="<?php echo $wishID; ?>">
           <input type="submit" name="editWish" value="Edit">
        </form>
    </td>
    <?php
    endwhile;
    mysqli_free_result($result);
    ?>
</table>

. 表の行の構文を修正します。行を終了する</tr>\n文字を、期日のecho文から endwhile; のすぐ上の新しいecho文に移動します。

    while ($row = mysqli_fetch_array($result)):
        echo "<tr><td>" . htmlentities($row["description"]) . "</td>";
        echo "<td>" . htmlentities($row["due_date"]) . "</td></tr>\n";
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
           <input type="hidden" name="wishID" value="<?php echo $wishID; ?>">
           <input type="submit" name="editWish" value="Edit">
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    mysqli_free_result($result);
    ?>
</table>

. while ループ内に「Edit」ボタンを持つフォームを含む表の全体は、次のようになります。

MySQLデータベースの場合:

<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"]);
    $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>";
        $wishID = $row["id"];
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="editWish" value="Edit"/>
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    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>";
        $wishID = $row["ID"];
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="editWish" value="Edit"/>
        </form>
    </td>
    <td>
        <form name="deleteWish" action="deleteWish.php" method="POST">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="deleteWish" value="Delete"/>
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    oci_free_statement($stid);
   ?>
</table>

$wish 配列の拡張

`editWishList.php` ページで「Edit」ボタンを押すと、選択したウィッシュのIDがサーバー・リクエスト・メソッドGETを介して `editWish.php` ページに転送されます。ウィッシュのIDを格納するには、 `$wish` 配列に新しい要素を追加する必要があります。

新しいウィッシュを追加するときに、それを保存しようとして失敗した後で、 editWishList.php ページと editWish.php ページの両方から入力フォームにアクセスできます。データを転送するサーバー・リクエスト・メソッドによって、ケースが識別されます。GETは、ユーザーが「Edit Wish」を押して最初にページに達するときに、フォームが表示されることを示します。POSTは、説明なしでウィッシュを保存しようとした後、ユーザーがフォームにリダイレクトされることを示します。

`editWish.php` 内で、HTML <body>内の `EditWish` 入力フォームの上にあるPHPブロックを、 `$wish` 配列の拡張されたコードで置き換えます。

MySQLデータベースの場合:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST")
    $wish = array("id" => $_POST["wishID"], "description" =>
            $_POST["wish"], "due_date" => $_POST["dueDate"]);
else if (array_key_exists("wishID", $_GET))
    $wish = mysqli_fetch_array(WishDB::getInstance()->get_wish_by_wish_id($_GET["wishID"]));
else
    $wish = array("id" => "", "description" => "", "due_date" => "");
?>

Oracleデータベースの場合:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST")
    $wish = array("id" => $_POST["wishID"], "description" =>
                $_POST["wish"], "due_date" => $_POST["dueDate"]);
else if (array_key_exists("wishID", $_GET)) {
    $stid = WishDB::getInstance()->get_wish_by_wish_id($_GET["wishID"]);
    $row = oci_fetch_array($stid, OCI_ASSOC);
    $wish = array("id" => $row["ID"], "description" =>
                $row["DESCRIPTION"], "due_date" => $row["DUE_DATE"]);
    oci_free_statement($stid);
} else
    $wish = array("id" => "", "description" => "", "due_date" => "");
?>

このコードは、 iddescription 、および due_date の3つの要素を持つ $wish 配列を初期化します。これらの要素の値はサーバー・リクエスト・メソッドに依存します。サーバー・リクエスト・メソッドがPOSTの場合、値は入力フォームから受け取ります。また、サーバー・リクエスト・メソッドがGETで、$_GET配列にキー「wishID」を持つ要素が含まれている場合、値は関数get_wish_by_wish_idによってデータベースから取得されます。最後に、サーバー・リクエスト・メソッドがPOSTおよびGET以外の場合、つまり新しいウィッシュの追加のユース・ケースが行われた場合、要素は空になります。

前述のコードは、ウィッシュを作成および編集するケースをカバーしています。また、入力フォームを両方のケースに使用できるように、入力フォームを更新する必要があります。

HTML入力フォームの更新

現時点では、新しいウィッシュを作成するとき、ウィッシュIDがなくても入力フォームは機能します。既存のウィッシュを編集する場合にフォームが機能するようにするには、ウィッシュのIDを転送するための非表示フィールドを追加する必要があります。非表示フィールドの値は、$wish配列から取得されます。新しいウィッシュの作成中、この値は空の文字列です。ウィッシュが編集される場合、非表示フィールドの値がウィッシュのIDに変わります。この非表示フィールドを作成するには、 editWish.phpEditWish 入力フォームの先頭に次の行を追加します。

<input type="hidden" name="wishID" value="<?php echo  `$wish` ["id"];?>" />

データベース内のウィッシュの更新

入力データを確認してウィッシュをデータベースに挿入するコードを更新する必要があります。現在のコードは、新しいウィッシュを作成するケースと既存のウィッシュを更新するケースを区別しません。現在の実装では、コードが入力フォームから転送されたウィッシュIDの値を確認しないため、新しいレコードは常にデータベースに追加されます。

次の機能を追加する必要があります。

  • 転送された要素「wishID」が空の文字列の場合、新しいウィッシュを作成する。

  • また、要素「wishID」が空の文字列でない場合、ウィッシュを更新する。

ウィッシュが新規であるかどうかを確認し、新規でない場合はウィッシュを更新するようにeditWish.phpを更新するには:

  1. update_wish 関数を db.php に追加します。

MySQLデータベースの場合:

public function update_wish($wishID, $description, $duedate) {
    $description = $this->real_escape_string($description);
    if ($duedate==''){
        $this->query("UPDATE wishes SET description = '" . $description . "',
            due_date = NULL WHERE id = " . $wishID);
    } else
        $this->query("UPDATE wishes SET description = '" . $description .
            "', due_date = " . $this->format_date_for_sql($duedate)
            . " WHERE id = " . $wishID);
}

Oracleデータベースの場合:

public function update_wish($wishID, $description, $duedate) {
    $query = "UPDATE wishes SET description = :desc_bv, due_date = to_date(:due_date_bv, 'YYYY-MM-DD')
                WHERE id = :wish_id_bv";
    $stid = oci_parse($this->con, $query);
    oci_bind_by_name($stid, ':wish_id_bv', $wishID);
    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);

}

. get_wish_by_wish_id 関数を db.php に追加します。

MySQLデータベースの場合:

public function get_wish_by_wish_id ($wishID) {
    return $this->query("SELECT id, description, due_date FROM wishes WHERE id = " . $wishID);
}

Oracleデータベースの場合:

public function get_wish_by_wish_id($wishID) {
    $query = "SELECT id, description, due_date FROM wishes WHERE id = :wish_id_bv";
    $stid = oci_parse($this->con, $query);
    oci_bind_by_name($stid, ':wish_id_bv', $wishID);
    oci_execute($stid);
    return $stid;
}
  1. editWish.php のメインとなる先頭のPHPブロックで、最後の`else`文に条件を追加します。これはデータベースにウィッシュを挿入する else 文です。これを else if 文に変更します。

else if ($_POST["wishID"]=="") {
    WishDB::getInstance()->insert_wish($wisherID, $_POST["wish"], $_POST["dueDate"]);
    header('Location: editWishList.php' );
    exit;
}
  1. 別の else if 文を、前に編集した文の下に入力するか、または貼り付けます。

else if ($_POST["wishID"]!="") {
    WishDB::getInstance()->update_wish($_POST["wishID"], $_POST["wish"], $_POST["dueDate"]);
    header('Location: editWishList.php' );
    exit;
}

このコードは、 $_POST 配列内の wishID 要素が空の文字列ではないことを確認します(これは、ユーザーが「Edit」ボタンを押すことによって editWishList.php ページからリダイレクトされたこと、および、ユーザーがウィッシュの説明を入力していたことを意味します)。確認が成功すると、コードは入力パラメータ wishIDdescription 、および dueDate を使用して関数 update_wish をコールします。これらのパラメータは、HTML入力フォームからPOSTメソッドを介して受け取ります。 update_wish がコールされた後、アプリケーションは editWishList.php ページにリダイレクトされ、PHP処理は取り消されます。

ウィッシュの編集機能のテスト

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

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

edit wish list edit wish
  1. 「Icecream」の横の「Edit」をクリックします。 editWish.php ページが開きます。

edit wish
  1. フィールドを編集して「Back to the List」を押します。 editWishList.php ページが開きますが、変更は保存されていません。

  2. 「Icecream」の横の「Edit」を押します。「Describe your wish」フィールドをクリアして「Save Changes」を押します。エラー・メッセージが表示されます。

editWishEmptyDescription
  1. 「Describe your wish」フィールドに「Chocolate icecream」と入力し、「Save Changes」を押します。 editWishList.php ページが開き、更新されたリストが表示されます。

editWishListWishAdded

ウィッシュの削除

ウィッシュの作成、読取り、更新ができるようになったので、ウィッシュを削除するメソッドを追加します。

ユーザーがウィッシュを削除できるようにするには:

  1. delete_wish 関数を db.php に追加します。

MySQLデータベースの場合:

function delete_wish ($wishID){
    $this->query("DELETE FROM wishes WHERE id = " . $wishID);
}

Oracleデータベースの場合:

public function delete_wish($wishID) {
    $query = "DELETE FROM wishes WHERE id = :wish_id_bv";
    $stid = oci_parse($this->con, $query);
    oci_bind_by_name($stid, ':wish_id_bv', $wishID);
    oci_execute($stid);
}
  1. deleteWish.php という名前の新しいPHPファイルを作成し、次のコードを<?php?>ブロック内に入力します。

require_once("Includes/db.php");
WishDB::getInstance()->delete_wish ($_POST["wishID"]);
header('Location: editWishList.php' );

このコードにより、 db.php ファイルが使用できるようになります。入力パラメータとして wishID を使用し、WishDBのインスタンスから delete_wish 関数をコールします。最後に、アプリケーションが editWishList.php ページにリダイレクトされます。

  1. 「Delete」ボタンを実装するには、別のHTML表のセルを、 editWishList.phpwhile ループの内部で、 editWish ボタンのコード・ブロックのすぐ下に追加します。HTML入力フォームには、 wishID 用の非表示フィールドと、「Delete」というラベルが付いた送信ボタンが含まれています。(MySQLデータベース用のコードが示されていますが、追加されるコードはOracleデータベースの場合も同じで、同じ場所になります。)

    while ($row = mysqli_fetch_array($result)):
        echo "<tr><td>" . htmlentities($row["description"]) . "</td>";
        echo "<td>" . htmlentities($row["due_date"]) . "</td></tr>\n";
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
           <input type="hidden" name="wishID" value="<?php echo $wishID; ?>">
           <input type="submit" name="editWish" value="Edit">
        </form>
    </td>
    <td>
        <form name="deleteWish" action="deleteWish.php" method="POST">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="deleteWish" value="Delete"/>
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    mysqli_free_result($result);
    ?>
</table>
`while` ループ内に「Edit」ボタンを持つフォームを含む表の全体は、次のようになります。

MySQLデータベースの場合:

<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"]);
    $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>";
        $wishID = $row["id"];
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="editWish" value="Edit"/>
        </form>
    </td>
    <td>
        <form name="deleteWish" action="deleteWish.php" method="POST">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="deleteWish" value="Delete"/>
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    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>";
        $wishID = $row["ID"];
    ?>
    <td>
        <form name="editWish" action="editWish.php" method="GET">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="editWish" value="Edit"/>
        </form>
    </td>
    <td>
        <form name="deleteWish" action="deleteWish.php" method="POST">
            <input type="hidden" name="wishID" value="<?php echo $wishID; ?>"/>
            <input type="submit" name="deleteWish" value="Delete"/>
        </form>
    </td>
    <?php
    echo "</tr>\n";
    endwhile;
    oci_free_statement($stid);
   ?>
</table>

ウィッシュの削除機能のテスト

機能が正しく実装されたことを確認するには、 editWishList.php ページで任意の項目の横にある「Delete」を押します。その項目がリストに表示されなくなります。

deleteWish

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

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

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

次の手順

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