簡易コメント追加 Script


ドキュメント履歴: 2020-08-27 初回アップ

はじめに
私のページには、来訪者が書き込めるページとして簡易掲示板のようなページはあったが、ブログのようにページ単位でコメントする機能や、記入者のページにリンクを貼る機能はなかった。
まぁ個人的には、2003年から e日記なるブログの元になるような cgiでページ出力するシステムを自作したりして来たので、安易にブログのマネなんて・・・と言う気持ちもあったが、変更のアイデアはずっと頭の中にあったので、何とか形にしようと老骨!に鞭打って 生噛りのphpと 主体は perlによる htmlに追加できる簡易コメント機能を作ってみた。
ここでは phpで perlを呼んで perl の処理結果を phpに返して表示するワザなどを含めて習得したノウハウを披瀝する。(Web検索では 「外部プログラムの実行は exec()コマンドを使う」と言う説明が見つかるが、意外と実際の exec() の使用例のサンプルコードは見つからない)
全て phpで書けば何ていうことはないのかも知れないが、こうすることで何とか自分でスクリプトを書ける perlの処理をメインにして、自分なりに htmlファイル側への追加は最小限(約10行)にすることができた(と思う)。


  1. html内で phpを実行して、perlスクリプト を呼ぶ
  2. 全体フロー
  3. コメント欄表示スクリプトの処理概要
  4. 記入コメントの登録処理スクリプトの処理概要


  1. html内で phpを実行して、perlスクリプト を呼ぶ
  2. phpスクリプトはサーバーの .htaccess ファイルに
    <FilesMatch "\.html$">
    		AddType application/x-httpd-php .htm .html .php
    		</FilesMatch>
    と記述しておけば、htmlファイル中に phpスクリプトを埋め込んで実行することが出来る。
    上記の2行目は
    AddHandler php7-script .htm .html .php
    でも可能。いずれも .php .htm .html という拡張子のページに phpスクリプトがあったら文字列として表示しないでプログラムとして実行してね! という指示になる。htmlのままでプレーンな htmlタグなどのコードを記述しても静的な表示しか出来ないが、phpなどのプログラムが実行できると、例えばコメント投稿があった場合にコードを変えないでもそのコメントを表示追加出来るなど、より動的なページが実現できる。
    例えば、このページの下の方のコメント記入欄や(もしコメントがあれば)そのコメントを表示するのに本体htmlへの追加は僅か 10行ほどのコードを記述するだけ。そのコード中で指定されたプログラムが実際に表示する記入欄やコメントのストリングを出力する。
    perl スクリプトでも <iframe> タグを用いて同一ページの別フレームに実行結果を表示することは可能だが、iframe と言う仕切りの中に表示することになるのに対して、php スクリプトでは完全に html とシームレスになるので、比べると柔軟性が高い(と思う)。
    php について 従来から私は ページ内で繰り返し使う文字列を
     <?php include_once("sample.txt") ?> 
    のようにしてインクルードしていたが、今回は単に文字列を表示するだけでなく、指定したファイルをプログラムとして実行して結果を受け取って表示すると言う処理をしたかった。
    多分、phpに長けた人なら全て phpで書いてしまうんだろうけど、残念ながら私は php に関してそこまで精通していないし、コーディングしながら勉強というのもハードルが高い。
    しかし perl なら何とか書けるかも?と思って、例えば sample.pl という perlスクリプトを phpで実行できるのでは? と思い立った。
    いろいろ調べて include() の代わりに exec() というコマンドを使えば出来そうだと分かり、早速チャレンジ。
    例えば下のように /route/dir1/dir2/sample.html の中の phpコマンド exec() で test.pl を呼び出して実行する場合
    /route ---- /dir1/dir2/sample.html
    			|
    			---/usr/bin/test/test.pl
    外部スクリプトを実行する実際のコマンド行は sample.html から見た test.pl の相対的パス(../../usr/bin/test/test.pl)を指定して以下のように記述する。
    $result = exec("/usr/bin/perl ../../usr/bin/test/test.pl $argv1 $argv2", $out, $rtn);
    最初のブロック(/usr/bin/perl) は サーバールートからの perlの実行ファイルのディレクトリ(シェバング行と同じ)、 $argv1 $argv2 は test.plに渡す引数、それぞれの区切りは半角スペース
    $out は配列変数で text.pl内で実行した print 文の結果が収納される。($result には最後の要素だけが入る)
    $rtn には 実行が成功した場合 "0" が、失敗した場合 それ以外(127とか 2とか)が返される。
    注意しないといけないのは、引数の区切りで それぞれの引数が文字列だった場合に空白文字が含まれると別引数として扱われてしまうようだ。(2個渡しても 3個として扱われる) どうしても空白文字を引数として渡したいなら"\s"などに置換してから渡して、受け取った方のスクリプトで空白に置き換えるなどの処理が必要だと思う。今回の私のスクリプトでは引数は親htmlのURLだけで、ファイル名には空白文字を使用していないのでそうした処理は入れていない。
    実行結果は if($rtn === 0) なら配列 $out を順次表示することで、perlスクリプト内の標準出力への出力(print文の結果)が表示される。
    こうして起動した perlスクリプトでコメント記入用 FORMと、ログから該当するページへのコメントを検索してヒットしたコメントのタイトルや投稿者ID、日付などを テーブルの該当セルに print することでコメント欄が実現する。
  3. 実際のフロー
  4. それぞれの親の htmlファイルには、実際には以下のようなスクリプトを追加する。
    <?php
    	$rqurl = $_SERVER['REQUEST_URI'];							// 親htmlの uri(ルートからのパス)
    	$cgi_path = str_repeat('../', count(explode("/", $rqurl)) - 2) . 'usr/bin/comment/comment_dsp.pl';
    	// ルートパスまでのディレクトリ階層を "../" で遡って cgi のパスを指定する
    		$result = exec("/usr/bin/perl $cgi_path $rqurl", $out, $rtn);
    		if($rtn === 0){
    			foreach($out as $value){
    			print_r($value . "\n");
    			}
    		}else{ echo "<br> // fail // <br> rtn: $rtn <br> route: $pcgi";}
    ?>
    以上のスクリプトを 親htmlのコメント機能を表示したい部分に追記することで、 phpから comment_dsp.plを起動して、comment_dsp.pl 内の処理でコメント記入FORMと該当htmlに対するコメントをコメントログファイルから読み出して表示することが出来る。
    1行目の $rqurl = $_SERVER['REQUEST_URI']; は親htmlページの URL文字列を返し、その次の行は親htmlから起動する perlスクリプトを指定するためのパスを生成するもので、こうすることで親htmlのファイル名や、異なる階層からの perlスクリプトのパスが自動的に生成されるので親htmlへの追記が画一化できる。
    一方、記入したコメントが post送信されてくると、それを解析してログファイルに記録する処理は、FORM内の action="" で指定した別の perlスクリプト(comment_wr.pl)で処理される。
  5. comment_dsp.pl の処理概要
  6. 上節で述べた 親htmlへの php追加スクリプトによって、外部 perlスクリプト(comment_dsp.pl)が起動されると コメント記入 FORMを表示し、更に コメントログファイルを開いて 該当ページ対するコメントがあればそれを表示する。
    実際の表示形態についてはこのページの下を参照。
    この記入FORMにコメントを記入して「送信」ボタンを押すと、別の perlスクリプト(comment_wr.pl)が起動してコメント記入されたデータのログへの記録など各種処理を行う。
  7. comment_wr.pl の処理概要
  8. 起動すると、post送信データを読み出してテンポラリファイルにコメントの内容を追記して、確認画面を表示し記入内容のチェックなどを行い投稿者が問題ないと判断して、「投稿」ボタンを押すとテンポラリファイルの名前を正式ログファイル名に変更するスクリプト。
    尚、現在の私のコーディングでは スパムなどの不適切書き込み対策として、一旦書き込まれたコメントは直後には表示されるが 一定時間後に非表示とされて、管理者が別のスクリプトで「表示承認」を行うことによって常時表示される機能となっている。
    また同じようにもう一つのスパム対策として同一IPからの再書き込みは一定時間受け付けないようになっている(私のページにはそれほど投稿価値があるとは思わないので)。
    現在のところ実際のスクリプトは公開予定はありませんが(日々変更を加えて進化中なので)、もし希望があれば下にコメントください。気が向けばスクリプト中に分かりやすいようなコメントを付加するなど若干手を加えて公開するかも知れません。
    【以下自分メモ】
    このスクリプトを実行する HTMLページにリーダーからコメントの書き込みがあると、所定のメアドあてに通知が送られる。また、管理用の別スクリプト admin.pl がセットになっておりこれを起動すると、コメント一覧リストが表示されて、コメントの表示許可/拒否 などの指定が可能になる。