▼ ノーマル ▼ スマホ 保存データを行単位で区切り文字で分けて投稿データを保存する方法は古くからありますが、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 要素を無効にする方法としては、htmlentities や htmlspecialchars がありますが、初心者向けとして最低限の置き換えを 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 + WEBアプリの最新記事】
- PHP : $.ajax でアップロード( 画像限定 ) / ファイルアップロード ver.3
- PHP : 選択した画像の表示 / ファイルアップロード ver.2
- PHP : ファイルアップロード ver.1
- PHP : 曲線が必要ならば ImageMagick ( 但し使えるかどうかはサーバー次第 )
- GD で画像縮小。『1) 単純縮小、2) 幅にあわす 3) 高さにあわす 4) 任意の幅と高さ』をその他の処理も含めてクラスでまとめ( class GD )
- PHP : 超簡易ログ
- PHP + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート
- Windows で Laravel を試す際、PHP の Windows バージョンが 5.6.30 なので、Laravel 5.2 をインストールします
- Laravel を試す為に Windows に Composer をインストール
- スマホ対応、サーバインデックス表示パッケージ( jQuery + Bootstrap(css) + mmenu + PHP )
- 超簡易掲示板 : 保存タイプは CSV
- PHP による『超簡易掲示板』 / アプリケーションからの POST 検証用
- PHP : 既存 GD 関連ライブラリで、背景をグラデーション(2)
- PHP : 既存 GD 関連ライブラリで、背景をグラデーション
- PHP : 入力値のデバッグ
- PHP : ImageMagick : 背景が透過する画像を作成
- PHP雛型(2会話DB更新処理) : MySQL、XMLHttpRequest、XML、JSON、Canvas
- PHP をテストする為の初心者用フォーム