PHPプログラミング

ワークショップ

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

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

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

この記事のポイント

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

目次

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

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

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

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

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

メッセージ内容を編集

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

編集内容が反映される

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

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

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

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

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

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

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

コード例

<?php

-- 省略 --

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

-- 省略 --

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

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

}

-- 省略 --

if文の条件式にPOSTパラメータの確認を加えているのは、URLに含めてデータを渡すGETパラメータはページを再読み込みしてもURLに残っていることがあるためです。
そのため、GETパラメータのみの確認だとPOSTパラメータが渡されていてもGETパラメータも同時に渡されているので最初のif文が実行されて更新処理は実行されません。

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

コード例

<?php

-- 省略 --

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

	$message_id = (int)htmlspecialchars( $_POST['message_id'], ENT_QUOTES);
	
	if( empty($_POST['view_name']) ) {
		$error_message[] = '表示名を入力してください。';
	} else {
		$message_data['view_name'] = htmlspecialchars($_POST['view_name'], ENT_QUOTES);
	}
	
	if( empty($_POST['message']) ) {
		$error_message[] = 'メッセージを入力してください。';
	} else {
		$message_data['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES);
	}

	if( empty($error_message) ) {
	
		// ここにデータベースに保存する処理が入る
	}
}

-- 省略 --

追記したコードの1行目は投稿IDのサニタイズです。
$message_idに整数型にサニタイズした値を代入しています。

続く2つのif文では、「表示名」と「メッセージ」の未入力バリデーションとサニタイズをそれぞれ行います。
empty関数で値が入っているかを確認し、もし未入力だった場合はエラーメッセージを$error_messageに代入します。

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

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

引き続き、データベースにデータを保存するコードを追記しましょう。

コード例

<?php

-- 省略 --

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

	$message_id = (int)htmlspecialchars( $_POST['message_id'], ENT_QUOTES);
	
	if( empty($_POST['view_name']) ) {
		$error_message[] = '表示名を入力してください。';
	} else {
		$message_data['view_name'] = htmlspecialchars($_POST['view_name'], ENT_QUOTES);
	}
	
	if( empty($_POST['message']) ) {
		$error_message[] = 'メッセージを入力してください。';
	} else {
		$message_data['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES);
	}

	if( empty($error_message) ) {
	
		// データベースに接続
		$mysqli = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME);
		
		// 接続エラーの確認
		if( $mysqli->connect_errno ) {
			$error_message[] = 'データベースの接続に失敗しました。 エラー番号 ' . $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
		} else {
			$sql = "UPDATE message set view_name = '$message_data[view_name]', message= '$message_data[message]' WHERE id =  $message_id";
			$res = $mysqli->query($sql);
		}
		
		$mysqli->close();
		
		// 更新に成功したら一覧に戻る
		if( $res ) {
			header("Location: ./admin.php");
		}
	}
}

-- 省略 --

データベースに接続する部分は今までと同じなので解説を省略します。

正常に接続した後、データを更新するSQLを作成してqueryメソッドで実行します。

$sql = "UPDATE message SET view_name = '$message_data[view_name]', message= '$message_data[message]' WHERE id =  $message_id";
$res = $mysqli->query($sql);

SQLには次の2つの内容が含まれます。

  1. UPDATE文で更新する「表示名」と「メッセージ」のデータをセット
  2. WHERE句に投稿IDを指定して更新する投稿データを検索する

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

WHERE句で更新するデータを特定する部分はSELECT文と共通です。

データの更新が正常に終了したら、管理ページに移動して終了します。

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

以上で編集した内容が反映されるようになりました。
仕上げとして、「// 変数の初期化」に使用する変数の宣言を記述しましょう。

コード例

<?php

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

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

// 変数の初期化
$message_id = null;
$mysqli = null;
$sql = null;
$res = null;
$error_message = array();
$message_data = array();

session_start();
-- 省略 --

メッセージの表示を修正する

管理ページの投稿を表示する部分でちょっとした修正を行います。
管理ページの「admin.php」を開き、メッセージを出力する箇所にnl2br関数を追記してください。

コード例


-- 省略 --

<?php if( !empty($message_array) ){ ?>
<?php foreach( $message_array as $value ){ ?>
<article>
	<div class="info">
		<h2><?php echo $value['view_name']; ?></h2>
		<time><?php echo date('Y年m月d日 H:i', strtotime($value['post_date'])); ?></time>
		<p><a href="edit.php?message_id=<?php echo $value['id']; ?>">編集</a>  <a href="delete.php?message_id=<?php echo $value['id']; ?>">削除</a></p>
	</div>
	<p><?php echo nl2br($value['message']); ?></p>
</article>
<?php } ?>
<?php } ?>

-- 省略 --

nl2br関数は、改行コードをHTMLのbr要素に置き換えて表示に反映してくれる関数です。
掲示板の「index.php」では、データベースを使う前にファイルへ保存する方式を取っていましたが、データを1行で保存する必要があるため手動で改行コードをbr要素に変換していました。

しかし現在はデータベースを使っているため、1行で保存する必要がなくなりました。
そこで、index.phpも管理ページと同様にnl2br関数で自動改行するように変更しておきましょう。

コード例


-- 省略 --

<section>
<?php if( !empty($message_array) ){ ?>
<?php foreach( $message_array as $value ){ ?>
<article>
	<div class="info">
		<h2><?php echo $value['view_name']; ?></h2>
		<time><?php echo date('Y年m月d日 H:i', strtotime($value['post_date'])); ?></time>
	</div>
	<p><?php echo nl2br($value['message']); ?></p>
</article>
<?php } ?>
<?php } ?>
</section>

-- 省略 --

不要になった手動でbr要素に置き換えていたコードも削除します。
次の赤字の箇所を1行削除してください。

コード例


-- 省略 --

	// メッセージの入力チェック
	if( empty($_POST['message']) ) {
		$error_message[] = 'ひと言メッセージを入力してください。';
	} else {
		$clean['message'] = htmlspecialchars( $_POST['message'], ENT_QUOTES);
		$clean['message'] = preg_replace( '/\\r\\n|\\n|\\r/', '<br>', $clean['message']);
	}

-- 省略 --

次のようになります。

	// メッセージの入力チェック
	if( empty($_POST['message']) ) {
		$error_message[] = 'ひと言メッセージを入力してください。';
	} else {
		$clean['message'] = htmlspecialchars( $_POST['message'], ENT_QUOTES);
	}

以上で修正完了です。

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

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

今回作成したコード:Github

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

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

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