PHPプログラミング

最終更新日:
公開日:

ワークショップ

ひと言掲示板を作る(20)

メッセージを編集する機能を実装する

「ひと言掲示板」の編集ページに編集内容をデータベースに保存する機能を実装していきます。

この記事のポイント

  • GETパラメータとPOSTパラメータで処理を切り替える
  • データを更新するSQLはUPDATE文を使う

目次

投稿されたメッセージを編集する

前回までは、ひと言掲示板に書き込まれた投稿を編集するためのページ「edit.php」を作成しました。
今回は、このページで編集した内容をデータベースに保存する機能を実装していきます。

今回の編集機能を実装すると、実際に投稿されたひと言メッセージの「表示名」や「メッセージ」が編集できるようになります。

管理ページで編集をクリック

管理ページ「admin.php」で、編集したいメッセージの「編集」リンクをクリックします。

メッセージ内容を編集

内容を編集し、「更新」ボタンを押すと編集内容がデータベースに保存され、メッセージの編集が完了します。

編集内容が反映される

「ひと言掲示板を作る」の概要については「ひと言掲示板を作る」をご覧ください。
デモはこちら

前回までに作成したコードはこちら:Github

POSTパラメータで「表示」と「更新」を切り替える

編集ページの表示、および編集内容をデータベースに保存するときはどちらも「edit.php」で実行します。
そこでまず、編集ページが開かれた時の「表示」と、編集内容をデータベースに保存する時の「更新」をパラメータから判別するように設定していきましょう。

POSTパラメータで処理を切り替えるイメージ

このように、POSTパラメータが渡されたかどうかで「表示」か「更新」かを判断していきます。

edit.php」を開いて、前回作成したGETパラメータを確認するif文の条件式にPOSTパラメータの確認を追加し、さらにデータを更新する時のためのelseif文を追加していきます。

edit.php

<?php

---- 省略 ----

if( !empty($_GET['message_id']) && empty($_POST['message_id']) ) {

---- 省略 ----

} elseif( !empty($_POST['message_id']) ) {

  // ここに編集内容を保存する処理が入る

}

---- 省略 ----

if文の条件式にPOSTパラメータの確認を加えましたが、ここでは渡されたパラメータがGETパラメータのみであるように変更しています。
この場合、もしURLにGETパラメータが残ったまま編集が実行されてもPOSTパラメータが渡されていたら更新が実行されるようになります。

続いて、編集内容を保存するコードを書いていきましょう。
渡されたPOSTパラメータをいきなりデータベースに保存するのではなく、投稿のときと同様に前準備として「空白除去」と「バリデーション」を実行します。

edit.php

<?php

---- 省略 ----

} elseif( !empty($_POST['message_id']) ) {

  // 空白除去
  $view_name = preg_replace( '/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $_POST['view_name']);
  $message = preg_replace( '/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $_POST['message']);

  // 表示名の入力チェック
  if( empty($view_name) ) {
    $error_message[] = '表示名を入力してください。';
  }

  // メッセージの入力チェック
  if( empty($message) ) {
    $error_message[] = 'メッセージを入力してください。';
  }

  if( empty($error_message) ) {

    // ここにデータベースに保存する処理が入る
  }
}

---- 省略 ----

編集ではセッションによる保存は必要ないため、投稿のときにバリデーションのif文とセットで書いていたelse文はありません。

3つ目のif文で、$error_messageにエラーメッセージが入っているか確認を行い、未入力の項目があったか確認します。
ここでエラーがないときのみ、データベースに編集したデータを保存するようにします。

編集したデータを保存する

引き続き、データベースにデータを保存するコードを追記しましょう。
追記するコードがやや多めですが、基本的な流れは「index.php」のひと言メッセージの投稿と共通しています。

edit.php

<?php

---- 省略 ----

} elseif( !empty($_POST['message_id']) ) {

  // 空白除去
  $view_name = preg_replace( '/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $_POST['view_name']);
  $message = preg_replace( '/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $_POST['message']);

  // 表示名の入力チェック
  if( empty($view_name) ) {
    $error_message[] = '表示名を入力してください。';
  }

  // メッセージの入力チェック
  if( empty($message) ) {
    $error_message[] = 'メッセージを入力してください。';
  }

  if( empty($error_message) ) {

    // トランザクション開始
    $pdo->beginTransaction();

    try {

      // SQL作成
      $stmt = $pdo->prepare("UPDATE message SET view_name = :view_name, message= :message WHERE id = :id");

      // 値をセット
      $stmt->bindParam( ':view_name', $view_name, PDO::PARAM_STR);
      $stmt->bindParam( ':message', $message, PDO::PARAM_STR);
      $stmt->bindValue( ':id', $_POST['message_id'], PDO::PARAM_INT);

      // SQLクエリの実行
      $stmt->execute();

      // コミット
      $res = $pdo->commit();

    } catch(Exception $e) {

      // エラーが発生した時はロールバック
      $pdo->rollBack();
    }

    // 更新に成功したら一覧に戻る
    if( $res ) {
      header("Location: ./admin.php");
      exit;
    }
  }
}

---- 省略 ----

今回はデータを新しく登録するのではなく「更新」になるため、SQLのUPDATE文を作成してプリペアドステートメントで実行します。

SET句はデータを更新したいカラムと値をセットで指定します。
更新するカラムが複数ある場合は「, (コンマ)」で区切って指定することができます。

更新する投稿を絞る必要がありますが、その処理はWHERE句でカラム「id」とPOSTパラメータで渡されたmessage_idを使って検索します。
ここで該当するidを持つ投稿が見つかったときに、bindParamメソッドでセットした表示名とメッセージをデータベースに反映します。

データの更新が正常に終了すると、header関数を使って管理ページに移動して更新は終了です。

edit.php

// 更新に成功したら一覧に戻る
if( $res ) {
  header("Location: ./admin.php");
  exit;
}

以上で編集した内容が反映されるようになりました。
ここで、「// 変数の初期化」で使用する変数の宣言と不要なコードを削除しましょう。
最終的には以下の赤字になっているコードのようになります。

edit.php

<?php

// データベースの接続情報
define( 'DB_HOST', 'localhost');
define( 'DB_USER', 'root');
define( 'DB_PASS', 'password');
define( 'DB_NAME', 'board');

// タイムゾーン設定
date_default_timezone_set('Asia/Tokyo');

// 変数の初期化
$view_name = null;
$message = array();
$message_data = null;
$error_message = array();
$pdo = null;
$stmt = null;
$res = null;
$option = null;

session_start();

---- 省略 ----

投稿の編集内容にエラーがあったときのために、編集入力フォームに入力値を表示するように設定します。

edit.php

---- 省略 ----

<form method="post">
  <div>
    <label for="view_name">表示名</label>
    <input id="view_name" type="text" name="view_name" value="<?php if( !empty($message_data['view_name']) ){ echo $message_data['view_name']; } elseif( !empty($view_name) ){ echo htmlspecialchars( $view_name, ENT_QUOTES, 'UTF-8'); } ?>">
  </div>
  <div>
    <label for="message">ひと言メッセージ</label>
    <textarea id="message" name="message"><?php if( !empty($message_data['message']) ){ echo $message_data['message']; } elseif( !empty($message) ){ echo htmlspecialchars( $message, ENT_QUOTES, 'UTF-8'); } ?></textarea>
  </div>
  <a class="btn_cancel" href="admin.php">キャンセル</a>
  <input type="submit" name="btn_submit" value="更新">
  <input type="hidden" name="message_id" value="<?php if( !empty($message_data['id']) ){ echo $message_data['id']; } elseif( !empty($_POST['message_id']) ){ echo htmlspecialchars( $_POST['message_id'], ENT_QUOTES, 'UTF-8'); } ?>">
</form>
</body>
</html>

表示名、ひと言メッセージ、そして非表示にしている投稿IDの3つに、それぞれ既存の入力値がある場合はそちらを出力するように設定しました。
入力値は出力するときにhtmlspecialchars関数でサニタイズしておきます。

ここまでの変更を保存したら、ブラウザで管理ページを表示して投稿の修正ができるようになっているか確認してみてください。
冒頭のように編集したい投稿の「編集」をクリックし、編集後に「更新」ボタンを押して反映されたら成功です。

今回はここまでとなります。
次回からは投稿の削除機能を実装していきます。

今回作成したコード:Github

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。