SQLの窓

2020年06月19日


超簡易掲示板 ( JSON ) : PHP / CSS でスマホ用レスポンシブ対応

▼ ノーマル

▼ スマホ




保存データを行単位で区切り文字で分けて投稿データを保存する方法は古くからありますが、JSON 形式で保存しておくと、投稿データ内の改行やクォートなどのデータを自分で処理する必要がなくなる上に、新しい項目も追加するのが容易になります。さらに、データが JSON で作られるので、そのまま http で他のアプリケーションからアクセスする事も容易になります

一応、MVC にのっとり、M(model.php) / V(view.php) / C(board.php) になっています

board.php

error_reporting(E_ALL & ~E_NOTICE); は、$_POST 等の変数の参照時に未定義(ブラウザから送られていない)時にでも、空文字列が入っているとみなして処理できるようにするものです。逆に、全てのエラーを出力するようにした場合、代入されていな い値を使用した場合は、警告を発生します( 必要であれば、php.ini で設定します )

<?php
error_reporting( E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED );
// **************************************
// php.ini の output_buffering をチェックして
// 有効になっていた場合は、header の前に出力可能です
// **************************************

// **************************************
// 通常の HTML として出力します
// **************************************
header( "Content-Type: text/html; charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダを出力する
// **************************************
session_cache_limiter('nocache');
session_start();


// **************************************
// グローバル変数
// **************************************
$logfile = "./board.log";
$log_text = "";

// **************************************
// 関数の定義を読み込みます
// **************************************
require_once("model.php");

// **************************************
// $_POST['send'] != "" は送信ボタンが
// クリックされた事を示します
// さらに、テキストエリアに何か入力され
// た場合に処理を行います
// **************************************
$_POST['text'] = preg_replace( "/^[ \s]+/u", "", $_POST['text'] );
$_POST['text'] = preg_replace( "/[ \s]+$/u", "", $_POST['text'] );
if ( $_POST['send'] != "" && $_POST['text'] != "" ) {

	// データの書き込み処理
	post_data();

}

// データの表示処理
disp_data();


// **************************************
// ▼ 以下は画面です。$log_text を
//    埋め込んでいます
// **************************************
require_once("view.php");
?>

FORM は一般的な POST メソッドで送信されます。なので、書き込んだ直後にリダイレクトして GET メソッドで呼び出しなおすという処理が入っています。タイトルの『超簡易掲示板 ( JSON )』をクリックすると、GET メソッドでの呼び出しであるリンクとなっています。

投稿データの表示内容は、いったん文字列で作成して後から view.php の該当部分に埋め込む形式です。最新のデータは、array_unshift によって、データの先頭に追加されます。

HTML 要素を無効にする方法としては、htmlentitieshtmlspecialchars がありますが、初心者向けとして最低限の置き換えを str_replace で実装しています。

json_encode による、オブジェクトから文字列の変換では、オプションの JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT でデバッグしやすいように可読性に重点を置いています。

model.php
<?php

// **************************************
// データの書き込み処理
// **************************************
function post_data() {

	global $logfile;

	// データを一括読み込み
	$log_text = @file_get_contents( $logfile );

	$json = json_decode( $log_text );
	// 空のファイルかまたは、JSON データでは無い場合
	if ( $json === null ) {

		// JSON 用クラス作成
		$json = new stdClass;
		// 行データを格納する配列を作成
		$json->item = [];

	}

	foreach( $_POST as $key => $value ) {

		// HTML 要素を無効にする
		$_POST[$key] = htmlspecialchars( $value );

	}

	// 改行コードを \n のみ(1バイト)にする
	$_POST['text'] = str_replace("\r","",$_POST['text']);

	// 新しい投稿用のクラス作成
	$board_data = new stdClass;

	// text プロパティに 入力された本文をセット
	$board_data->text = $_POST['text'];
	// subject プロパティに 入力されたタイトルをセット
	$board_data->subject = $_POST['subject'];
	// name プロパティに 入力された名前をセット
	$board_data->name = $_POST['name'];
	// subject プロパティに 入力されたタイトルをセット
	$board_data->datetime = $_POST['datetime'];

	// 配列の先頭に 新しい投稿データをセット
	array_unshift($json->item, $board_data);

	// 全ての投稿データを JSON として一括書き込み
	file_put_contents( $logfile, json_encode( $json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ) );

	// GET メソッドで再表示します
	header( "Location: {$_SERVER["PHP_SELF"]}" );

	exit();


}

// **************************************
// データの表示処理
// **************************************
function disp_data() {

	global $logfile;

	// 埋め込み用データを global 宣言
	global $log_text;

	// データを一括読み込み
	$log_data = @file_get_contents( $logfile );
	// ファイルが存在しない場合
	if ( $log_data === false ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	$json = json_decode( $log_data );
	// 空のファイルかまたは、JSON データでは無い
	if ( $json === null ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	// 表示用の埋め込みに使用される文字列変数
	foreach( $json->item as $v ) {
	
		// **************************************
		// 本文の改行は br 要素で表現します
		// **************************************
		$v->text = str_replace("\n", "<br>\n", $v->text );

		// **************************************
		// 記事の境界を hr 要素で表現します
		// **************************************
		$v->text .= "<hr>\n";

		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$log_text .= "<div class='title'>【{$v->subject}】( {$v->name} : {$v->datetime} ) </div>" . $v->text;
	
	}


}

?>


投稿時の日付データは、ブラウザ側でセットするようにしています。特に日付に関しては JavaScript ではスマートな方法が無いので、学習のきっかけ用としてこのようになっています。また、送信時のイベント処理としても重要なサンプルとなり、jQuery の基本サンプルでもあります。

※ jQuery は、Google のホスティングを使用しています。

view.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.0-alpha1/css/bootstrap.min.css" />
<link rel="stylesheet" href="board.css?_=<?= time() ?>">

<script>

$( function(){

	// フォーム送信イベント
	$("form").on("submit", function(){

		// 日付文字列をクライアントで作成して送信
		var dateNow = new Date();
		var dateString = 
			dateNow.getFullYear() + "/" + 
			("0"+(dateNow.getMonth()+1)).slice(-2)+ "/" + 
			("0"+(dateNow.getDate())).slice(-2);
		var timeString = 
			("0"+(dateNow.getHours())).slice(-2) + ":" + 
			("0"+(dateNow.getMinutes())).slice(-2) + ":" + 
			("0"+(dateNow.getSeconds())).slice(-2);

		// hidden フィールドにセット
		$("#datetime").val( dateString + " " + timeString );

	});
});

</script>
</head>

<body>
<div id="bbs">
	<h3><a href="board.php" style="color:black;">超簡易掲示板 ( JSON )</a></h3>

	<form method="POST">
		<div>タイトル <input type="text" name="subject"></div>
		<div>名  前 <input type="text" name="name"></div>
		<div><textarea name="text"></textarea>
		<input type="hidden" name="datetime" id="datetime"></div>
		<div><input type="submit" name="send" value="送信"></div>
	</form>
	<br>

	<?= $log_text ?>

</div>
</body>
</html>

board.css
@charset "utf-8";

* {
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}

textarea {
	height: 100px;
}

/* PC 用 */
@media screen and ( min-width:480px ) {

	#bbs {
		padding: 20px;
	}

	input {
		width: 400px;
	}
	textarea {
		width: 500px;
	}
}

/* スマホ 用 */
@media screen and ( max-width:479px ) {

	#bbs {
		padding: 0px;
	}

	input,textarea {
		width:100%;
	}

}

.title {
	border: 1px solid #aaa;
	padding: 4px;
	margin-bottom: 6px;
}



JSON は、item プロパティが配列になり、複数項目の投稿データが格納されます。

JSON データ
{
    "item": [
        {
            "text": "最低限の機能を持った掲示板です。\nデータ形式は JSON でとても拡張しやすく便利です。",
            "subject": "こんにちは",
            "name": "山田 タロウ",
            "datetime": "2019\/02\/22 13:48:00"
        }
    ]
}




タグ:PHP 掲示板
【PHP + WEBアプリの最新記事】
posted by lightbox at 2020-06-19 11:30 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり