PHPプログラミング

ワークショップ

ひと言掲示板を作る

投稿メッセージの編集ページを作る

「ひと言掲示板」に書き込まれた投稿を、管理ページから編集する機能を実装します。

この記事のポイント

  • GET形式のパラメータはリンクの後ろに「?」で区切って指定する
  • SQLのSELECT文にWHERE句を指定して取得データを絞り込む

目次

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

前回までは、ひと言掲示板の管理ページに投稿データをCSV形式でダウンロードする機能を実装してきました。
今回からは投稿されたメッセージを編集する機能を実装していきます。

編集&削除リンクの表示例

「編集」を押すと、次のように編集ページが開きます。

投稿の編集ページ表示例

編集ページは少し工数が多いため、今回と次回の2回に分けて作成していきます。

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

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

編集ページを作成する

編集ページは管理ページとは独立したページとして作成します。
次のように、管理ページで「編集」が押されると投稿IDを渡して編集ページを開き、編集ページで編集完了するか、キャンセルすると管理ページに戻るような構成です。

管理ページと編集ページのイメージ

まずは、編集ページとなる「edit.php」を作成しましょう。
index.php」を複製して、ファイル名を「edit.php」に変更してください。

複製したら、edit.phpを開いて「// 変数の初期化」からHTMLが始まる部分までのコードを一旦削除します。
セッションを開始するsession_start関数のみ残しておいてください。

コード例

<?php

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

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

// 変数の初期化


session_start();

?>
<!DOCTYPE html>

-- 省略 --

ログインセッションを確認する

編集ページはダウンロードページと同様に、運営者しかアクセスできないページです。
そこで、ログインセッションがあるかを確認しましょう。

コード例

<?php

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

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

// 変数の初期化


session_start();

// 管理者としてログインしているか確認
if( empty($_SESSION['admin_login']) || $_SESSION['admin_login'] !== true ) {

	// ログインページへリダイレクト
	header("Location: ./admin.php");
}

?>
<!DOCTYPE html>

-- 省略 --

もしログインセッションがない状態でアクセスされた場合は、header関数で管理ページ「admin.php」にリダイレクトする設定です。

ログインセッションの次に、編集する投稿を特定するための投稿IDが渡されているかを確認します。

コード例

<?php

-- 省略 --

session_start();

// 管理者としてログインしているか確認
if( empty($_SESSION['admin_login']) || $_SESSION['admin_login'] !== true ) {

	// ログインページへリダイレクト
	header("Location: ./admin.php");
}

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

	// 投稿を取得するコードが入る

}

-- 省略 --

GETパラメータで投稿IDである「message_id」が渡されていたら、if文の中で投稿IDに該当する投稿(メッセージ)をデータベースから取得します。

コード例

<?php

-- 省略 --

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

	$message_id = (int)htmlspecialchars($_GET['message_id'], ENT_QUOTES);
	
	// データベースに接続
	$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 = "SELECT * FROM message WHERE id = $message_id";
		$res = $mysqli->query($sql);
		
		if( $res ) {
			$message_data = $res->fetch_assoc();
		} else {
		
			// データが読み込めなかったら一覧に戻る
			header("Location: ./admin.php");
		}
		
		$mysqli->close();
	}
}

-- 省略 --

追記したコードを上から順に解説します。

まず、1行目はGETパラメータで渡された投稿IDをサニタイズして、$message_idに代入します。
この後のコードで、この投稿IDを使ってデータベースから投稿データを取得します。

続く「// データベースに接続」と「// 接続エラーの確認」については、これまでと同じ方法を使ったデータベース接続の手順になるので解説は省略します。
正常に接続できた場合はelse文の中で、SQLを作成してデータを取得していきます。

// データの読み込み
$sql = "SELECT * FROM message WHERE id = $message_id";
$res = $mysqli->query($sql);

この3行で、投稿データを取得するSQLの作成とデータ取得を行なっています。
データの取得なのでSELECT文を使用し、先ほどサニタイズした投稿ID$message_idをWHERE句に指定します。
これで、該当する投稿IDを持ったデータのみを取得することができます。

if( $res ) {
	$message_data = $res->fetch_assoc();
} else {

	// データが読み込めなかったら一覧に戻る
	header("Location: ./admin.php");
}

該当する投稿を取得できたら、連想配列形式で$message_dataにデータを代入します。
もし投稿が見つからなかった場合は$resfalseが入るため、else文の方で管理ページにリダイレクトさせています。

以上で該当する投稿メッセージのデータを取得することができました。
続いて、ここで取得したデータを使って編集ページを表示していきます。

編集ページのHTMLを作る

続いて、「index.php」にもともとある投稿フォームをベースにして編集ページを作成していきましょう。
まずは不要なパーツを削除していきます。
次の赤字になっているコードを削除してください。

コード例


-- 省略 --

<body>
<h1>ひと言掲示板</h1>
<?php if( !empty($success_message) ): ?>
	<p class="success_message"><?php echo $success_message; ?></p>
<?php endif; ?>
<?php if( !empty($error_message) ): ?>
	<ul class="error_message">
		<?php foreach( $error_message as $value ): ?>
			<li>・<?php echo $value; ?></li>
		<?php endforeach; ?>
	</ul>
<?php endif; ?>
<form method="post">
	<div>
		<label for="view_name">表示名</label>
		<input id="view_name" type="text" name="view_name" value="<?php if( !empty($_SESSION['view_name']) ){ echo $_SESSION['view_name']; } ?>">
	</div>
	<div>
		<label for="message">ひと言メッセージ</label>
		<textarea id="message" name="message"></textarea>
	</div>
	<input type="submit" name="btn_submit" value="書き込む">
</form>
<hr>
<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 $value['message']; ?></p>
</article>
<?php } ?>
<?php } ?>
</section>
</body>
</html>

削除した後は次のようになります。

コード例


-- 省略 --

<body>
<h1>ひと言掲示板</h1>
<?php if( !empty($error_message) ): ?>
    <ul class="error_message">
		<?php foreach( $error_message as $value ): ?>
            <li>・<?php echo $value; ?></li>
		<?php endforeach; ?>
    </ul>
<?php endif; ?>
<form method="post">
	<div>
		<label for="view_name">表示名</label>
		<input id="view_name" type="text" name="view_name" value="">
	</div>
	<div>
		<label for="message">ひと言メッセージ</label>
		<textarea id="message" name="message"></textarea>
	</div>
	<input type="submit" name="btn_submit" value="書き込む">
</form>
</body>
</html>

続いて、編集ページであることがわかるようにページタイトルを編集します。

コード例


-- 省略 --

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ひと言掲示板 管理ページ(投稿の編集)</title>
<style>

-- 省略 --

</style>
</head>
<body>
<h1>ひと言掲示板 管理ページ(投稿の編集)</h1>

-- 省略 --

先ほど取得したメッセージのデータを、フォームに表示するようにしていきます。
「表示名」と「メッセージ」にそれぞれ出力するコードを追記します。

コード例


-- 省略 --

<body>
<h1>ひと言掲示板 管理ページ(投稿の編集)</h1>
<?php if( !empty($error_message) ): ?>
    <ul class="error_message">
		<?php foreach( $error_message as $value ): ?>
            <li>・<?php echo $value; ?></li>
		<?php endforeach; ?>
    </ul>
<?php endif; ?>
<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']; } ?>">
	</div>
	<div>
		<label for="message">ひと言メッセージ</label>
		<textarea id="message" name="message"><?php if( !empty($message_data['message']) ){ echo $message_data['message']; } ?></textarea>
	</div>
	<input type="submit" name="btn_submit" value="書き込む">
</form>
</body>
</html>

どちらもempty関数で値があることを事前に確認し、値があるときのみ出力します。
続いて、編集をキャンセルする場合のリンクを追加します。

コード例


-- 省略 --

<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']; } ?>">
	</div>
	<div>
		<label for="message">ひと言メッセージ</label>
		<textarea id="message" name="message"><?php if( !empty($message_data['message']) ){ echo $message_data['message']; } ?></textarea>
	</div>
	<a class="btn_cancel" href="admin.php">キャンセル</a>
	<input type="submit" name="btn_submit" value="書き込む">
</form>
</body>
</html>

ついでに、「書き込む」ボタンのラベルを「更新」に変更しておきましょう。

コード例

<input type="submit" name="btn_submit" value="更新">

さらに、編集した内容を登録するときに内容を更新する投稿が分かるよう投稿IDをフォームにセットします。
こちらの値は誤って編集することの無いように、input要素type属性を「hidden」にして非表示の項目にしておきましょう。

コード例


-- 省略 --

<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']; } ?>">
	</div>
	<div>
		<label for="message">ひと言メッセージ</label>
		<textarea id="message" name="message"><?php if( !empty($message_data['message']) ){ echo $message_data['message']; } ?></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 echo $message_data['id']; ?>">
</form>

先ほど追加した「キャンセル」のリンクに、ボタンのような表示になるようCSSを追記します。
style属性の中であればどこに記述しても大丈夫です。
次の例では「掲示板エリア」というコメントの上に追記をしました。

コード例

-- 省略 --

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ひと言掲示板 管理ページ(投稿の編集)</title>
<style>

-- 省略 --

.success_message,
.error_message li {
    font-size: 86%;
    line-height: 1.6em;
}

.btn_cancel {
	display: inline-block;
	margin-right: 10px;
	padding: 10px 20px;
	color: #555;
	font-size: 86%;
	border-radius: 5px;
	border: 1px solid #999;
}
.btn_cancel:hover {
	color: #999;
	border-color: #999;
	text-decoration: none;
}


/*-----------------------------------
掲示板エリア
-----------------------------------*/

-- 省略 --

</style>
</head>

-- 省略 --

管理ページと編集ページを繋げる

最後に、ここまで作った編集ページと管理ページをリンクで繋げましょう。

admin.php」を開いて、投稿一覧を表示する部分にリンクを追記してください。
ここで、まだ作成していませんが削除ページのリンクもついでに設定してしまいます。

コード例

-- 省略 --

<?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 $value['message']; ?></p>
</article>
<?php } ?>
<?php } ?>

-- 省略 --

a要素href属性に編集ページのファイル名を指定し、さらに「?」で区切った上でGETパラメータとして投稿ID「message_id」を付与します。
これで、リンクをクリックしたときに投稿IDも同時に渡されるので、編集ページが開いた後にこのパラメータから投稿データを取得することができるようになります。

form要素とPOST形式とは異なるデータの送信方法ですが、投稿IDのような機密性がないデータについてはGET形式で渡すことが一般的です。

こちらのリンクについても、CSSを追記します。

コード例

-- 省略 --

	.info {
		margin-bottom: 10px;
	}
	.info h2 {
		display: inline-block;
		margin-right: 10px;
		color: #222;
		line-height: 1.6em;
		font-size: 86%;
	}
	.info time {
		color: #999;
		line-height: 1.6em;
		font-size: 72%;
	}
	.info p {
		display: inline-block;
		line-height: 1.6em;
		font-size: 86%;
	}
	article p {
		color: #555;
		font-size: 86%;
		line-height: 1.6em;
	}

-- 省略 --

今回作成した内容を、ブラウザから開いて確認してみましょう。
まずは管理ページを開いて、投稿ごとに表示されている「編集」のリンクをクリックしてください。

編集リンクを選択する

すると、次のように投稿メッセージの編集ページが表示されます。

編集ページの表示例

今はまだ表示部分しか作っていないため、まだ内容を編集しても何も起こりません。
「キャンセル」ボタンで一覧ページに戻れることを確認してみてください。

今回はここまでとなります。
次回は引き続き、編集した内容をデータベースに保存するように機能を追加していきます。

今回作成したコード:Github

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

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

ありがとうございます。
コメントを送信しました。