▼ ノーマル▼ スマホ
![]()
保存データを行単位で区切り文字で分けて投稿データを保存する方法は古くからありますが、JSON 形式で保存しておくと、投稿データ内の改行やクォートなどのデータを自分で処理する必要がなくなる上に、新しい項目も追加するのが容易になります。さらに、データが JSON で作られるので、そのまま http で他のアプリケーションからアクセスする事も容易になります 一応、MVC にのっとり、M(model.php) / V(view.php) / C(board.php) になっています board.php error_reporting(E_ALL & ~E_NOTICE); は、$_POST 等の変数の参照時に未定義(ブラウザから送られていない)時にでも、空文字列が入っているとみなして処理できるようにするものです。逆に、全てのエラーを出力するようにした場合、代入されていな い値を使用した場合は、警告を発生します( 必要であれば、php.ini で設定します )
01.
<?php
02.
error_reporting
(E_ALL & ~E_NOTICE);
03.
// **************************************
04.
// php.ini の output_buffering をチェックして
05.
// 有効になっていた場合は、header の前に出力可能です
06.
// **************************************
07.
08.
// **************************************
09.
// 通常の HTML として出力します
10.
// **************************************
11.
header(
"Content-Type: text/html; charset=utf-8"
);
12.
13.
// **************************************
14.
// キャッシュを無効にするヘッダ
15.
// ※ いろいろあるのは念のため
16.
// **************************************
17.
header(
"Expires: Thu, 19 Nov 1981 08:52:00 GMT"
);
18.
header(
"Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
);
19.
header(
"Pragma: no-cache"
);
20.
21.
// **************************************
22.
// 関数の定義を読み込みます
23.
// **************************************
24.
require_once
(
"model.php"
);
25.
26.
// **************************************
27.
// $_POST['send'] != "" は送信ボタンが
28.
// クリックされた事を示します
29.
// さらに、テキストエリアに何か入力され
30.
// た場合に処理を行います
31.
// **************************************
32.
$_POST
[
'text'
] = preg_replace(
"/^[ \s]+/u"
,
""
,
$_POST
[
'text'
] );
33.
$_POST
[
'text'
] = preg_replace(
"/[ \s]+$/u"
,
""
,
$_POST
[
'text'
] );
34.
if
(
$_POST
[
'send'
] !=
""
&&
$_POST
[
'text'
] !=
""
) {
35.
36.
// データの書き込み処理
37.
post_data();
38.
39.
}
40.
41.
// データの表示処理
42.
disp_data();
43.
44.
45.
// **************************************
46.
// ▼ 以下は画面です。$log_text を
47.
// 埋め込んでいます
48.
// **************************************
49.
require_once
(
"view.php"
);
50.
?>
キャッシュ無効は、先頭に session_cache_limiter('nocache'); session_start(); でもいいと思います FORM は一般的な POST メソッドで送信されます。なので、書き込んだ直後にリダイレクトして GET メソッドで呼び出しなおすという処理が入っています。タイトルの『超簡易掲示板 ( JSON )』をクリックすると、GET メソッドでの呼び出しであるリンクとなっています。 投稿データの表示内容は、いったん文字列で作成して後から view.php の該当部分に埋め込む形式です。最新のデータは、array_unshift によって、データの先頭に追加されます。 HTML 要素を無効にする方法としては、htmlentities や htmlspecialchars がありますが、初心者向けとして最低限の置き換えを str_replace で実装しています。 json_encode による、オブジェクトから文字列の変換では、オプションの JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT でデバッグしやすいように可読性に重点を置いています。 model.php
001.
<?php
002.
003.
// **************************************
004.
// データの書き込み処理
005.
// **************************************
006.
function
post_data() {
007.
008.
// データを一括読み込み
009.
$log_text
= @
file_get_contents
(
"board.log"
);
010.
011.
$json
= json_decode(
$log_text
);
012.
// 空のファイルかまたは、JSON データでは無い場合
013.
if
(
$json
=== null ) {
014.
015.
// JSON 用クラス作成
016.
$json
=
new
stdClass;
017.
// 行データを格納する配列を作成
018.
$json
->item =
array
();
019.
020.
}
021.
022.
// 改行コードを \n のみ(1バイト)にする
023.
$_POST
[
'text'
] =
str_replace
(
"\r"
,
""
,
$_POST
[
'text'
]);
024.
025.
// HTML 要素を無効にする
026.
$_POST
[
'text'
] =
str_replace
(
"<"
,
"<"
,
$_POST
[
'text'
]);
027.
$_POST
[
'text'
] =
str_replace
(
">"
,
">"
,
$_POST
[
'text'
]);
028.
029.
// HTML 要素を無効にする
030.
$_POST
[
'subject'
] =
str_replace
(
"<"
,
"<"
,
$_POST
[
'subject'
]);
031.
$_POST
[
'subject'
] =
str_replace
(
">"
,
">"
,
$_POST
[
'subject'
]);
032.
$_POST
[
'name'
] =
str_replace
(
"<"
,
"<"
,
$_POST
[
'name'
]);
033.
$_POST
[
'name'
] =
str_replace
(
">"
,
">"
,
$_POST
[
'name'
]);
034.
035.
// 新しい投稿用のクラス作成
036.
$board_data
=
new
stdClass;
037.
038.
// text プロパティに 入力された本文をセット
039.
$board_data
->text =
$_POST
[
'text'
];
040.
// subject プロパティに 入力されたタイトルをセット
041.
$board_data
->subject =
$_POST
[
'subject'
];
042.
// name プロパティに 入力された名前をセット
043.
$board_data
->name =
$_POST
[
'name'
];
044.
// subject プロパティに 入力されたタイトルをセット
045.
$board_data
->datetime =
$_POST
[
'datetime'
];
046.
047.
// 配列の先頭に 新しい投稿データをセット
048.
array_unshift
(
$json
->item,
$board_data
);
049.
050.
// 全ての投稿データを JSON として一括書き込み
051.
file_put_contents
(
"./board.log"
, json_encode(
$json
, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ) );
052.
053.
// GET メソッドで再表示します
054.
header(
"Location: {$_SERVER["
PHP_SELF
"]}"
);
055.
056.
exit
();
057.
058.
059.
}
060.
061.
// **************************************
062.
// データの表示処理
063.
// **************************************
064.
function
disp_data() {
065.
066.
// 埋め込み用データを global 宣言
067.
global
$log_text
;
068.
069.
// データを一括読み込み
070.
$log_text
= @
file_get_contents
(
"./board.log"
);
071.
// ファイルが存在しない場合
072.
if
(
$log_text
=== false ) {
073.
$log_text
=
"ここに投稿データが表示されます"
;
074.
return
;
075.
}
076.
077.
$json
= json_decode(
$log_text
);
078.
// 空のファイルかまたは、JSON データでは無い
079.
if
(
$json
=== null ) {
080.
$log_text
=
"ここに投稿データが表示されます"
;
081.
return
;
082.
}
083.
084.
// 表示用の埋め込みに使用される文字列変数
085.
$log_text
=
""
;
086.
foreach
(
$json
->item
as
$v
) {
087.
088.
// **************************************
089.
// 本文の改行は br 要素で表現します
090.
// **************************************
091.
$v
->text =
str_replace
(
"\n"
,
"<br>\n"
,
$v
->text );
092.
093.
// **************************************
094.
// 記事の境界を hr 要素で表現します
095.
// **************************************
096.
$v
->text .=
"<hr>\n"
;
097.
098.
// **************************************
099.
// 行毎に表示 HTML を作成
100.
// **************************************
101.
$log_text
.=
"<div class='title'>【{$v->subject}】( {$v->name} : {$v->datetime} ) </div>"
.
$v
->text;
102.
103.
}
104.
105.
106.
}
107.
108.
?>
投稿時の日付データは、ブラウザ側でセットするようにしています。特に日付に関しては JavaScript ではスマートな方法が無いので、学習のきっかけ用としてこのようになっています。また、送信時のイベント処理としても重要なサンプルとなり、jQuery の基本サンプルでもあります。 ※ jQuery は、Google のホスティングを使用しています。 view.php
01.
<!DOCTYPE html>
02.
<html>
03.
<head>
04.
<meta charset=
"utf-8"
>
05.
<meta content=
"width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no"
name=
"viewport"
>
06.
<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"
></script>
07.
08.
<style>
09.
* {
10.
font-family:
"ヒラギノ角ゴPro W3"
,
"Hiragino Kaku Gothic Pro"
,
"メイリオ"
,Meiryo,
"MS Pゴシック"
,Verdana,Arial,Helvetica,sans-serif;
11.
}
12.
13.
textarea {
14.
height: 100px;
15.
}
16.
17.
@media screen
and
( min-width:480px ) {
18.
input {
19.
width: 400px;
20.
}
21.
textarea {
22.
width: 500px;
23.
}
24.
}
25.
26.
@media screen
and
( max-width:479px ) {
27.
28.
input,textarea {
29.
width:100%;
30.
}
31.
32.
}
33.
34.
.title {
35.
border: 1px solid #aaa;
36.
padding: 4px;
37.
margin-bottom: 6px;
38.
}
39.
40.
</style>
41.
42.
<script>
43.
44.
$(
function
(){
45.
46.
// フォーム送信イベント
47.
$(
"form"
).on(
"submit"
,
function
(){
48.
49.
// 日付文字列をクライアントで作成して送信
50.
var
dateNow =
new
Date
();
51.
var
dateString =
52.
dateNow.getFullYear() +
"/"
+
53.
(
"0"
+(dateNow.getMonth()+1)).slice(-2)+
"/"
+
54.
(
"0"
+(dateNow.
getDate
())).slice(-2);
55.
var
timeString =
56.
(
"0"
+(dateNow.getHours())).slice(-2) +
":"
+
57.
(
"0"
+(dateNow.getMinutes())).slice(-2) +
":"
+
58.
(
"0"
+(dateNow.getSeconds())).slice(-2);
59.
60.
// hidden フィールドにセット
61.
$(
"#datetime"
).val( dateString +
" "
+ timeString );
62.
63.
});
64.
});
65.
66.
</script>
67.
</head>
68.
69.
<body>
70.
<h3><a href=
"board.php"
style=
"color:black;"
>超簡易掲示板 ( JSON )</a></h3>
71.
72.
<form method=
"POST"
>
73.
<div>タイトル <input type=
"text"
name=
"subject"
></div>
74.
<div>名 前 <input type=
"text"
name=
"name"
></div>
75.
<div><textarea name=
"text"
></textarea>
76.
<input type=
"hidden"
name=
"datetime"
id=
"datetime"
></div>
77.
<div><input type=
"submit"
name=
"send"
value=
"送信"
></div>
78.
</form>
79.
<br>
80.
81.
<?=
$log_text
?>
82.
83.
</body>
84.
</html>
JSON は、item プロパティが配列になり、複数項目の投稿データが格納されます。 JSON データ
01.
{
02.
"item"
: [
03.
{
04.
"text"
:
"最低限の機能を持った掲示板です。\nデータ形式は JSON でとても拡張しやすく便利です。"
,
05.
"subject"
:
"こんにちは"
,
06.
"name"
:
"山田 タロウ"
,
07.
"datetime"
:
"2019\/02\/22 13:48:00"
08.
}
09.
]
10.
}