前提・実現したいこと
PHPでデータベースを使わないコメント機能を作っています。
// 追記
ページ遷移の問題解決しました。あとはサニタイズの問題だけです。
https://web.analogstd.com/tips/posts/php/how-to-mount-comment-func-without-sql.php こちらのページを参考にしたのですが、コメントをするとそのページにとどまらずにPost先のphpファイルに移動してしまって困っています。エラーは特に出ていなく、メッセージも呼び出し元ページをリロードすればちゃんと書き込まれています。
あとサニタイズができなくて困っています。
何が問題なのかわかる方はご教授ください。
発生している問題・エラーメッセージ
ページ遷移せずに出力したいです。
あと、サニタイズのxhr_comment_send.phpでコメントアウトを外すと
php
1// サニタイズ 2$p_data['name'] = htmlspecialchars( $msg['name'], ENT_QUOTES); 3$p_data['message'] = htmlspecialchars( $msg['message'], ENT_QUOTES);
error
1Failed getting comment. 2```となってしまいます。 3 4### 該当のソースコード 5index.php 6```php 7<?php 8session_start(); 9include('../../assets/php/comments.php'); 10?> 11<!DOCTYPE HTML> 12<html lang="ja" dir="ltr" prefix="og: http://ogp.me/ns#"> 13 14<head> 15 <meta charset="utf-8"> 16 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 17 <!-- responsive --> 18 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> 19</head> 20<body> 21<center><a class="btn btn-2" href="javascript:history.back()">Back</a></center> 22 23 <aside id="show_comments" class="m_4r"> 24 <form class="m_b_4r" method="post" action="/assets/php/xhr_comment_send.php"> 25 <span class="ts tm">コメント</span> 26 <div class="fields" style="display: block;"> 27 <div class="field half"> 28 <div class="align-left"><label for="comment_name">Name</label></div> 29 <input type="text" name="name" id="comment_name" placeholder="Handle name" required> 30 <input type="hidden" name="id" value="<?php echo substr(base_convert(md5(session_id()), 16, 36), 0, 6); ?>"> 31 </div> 32 <div class="field half"> 33 <div class="align-left"><label for="comment_text">Comment</label></div> 34 <textarea id="comment_text" name="message" placeholder="お気軽にコメントください" rows="4" required></textarea> 35 </div> 36 </div> 37 <ul class="actions"> 38 <li><input id="comment_button" type="submit" value="Send Message" class="primary message_b" /></li> 39 <li><input id="reset_b" type="reset" value="Reset" /></li> 40 </ul> 41 </form> 42 <div class="align-left"> 43 <small>※短時間で連続してのコメントはできません。</small><br> 44 <small>※いたずら防止のためにIP アドレスを記録しています。ご了承願います。</small> 45 </div> 46 <?php 47 if(isset($comments)) { 48 // コメント部のHTMLを出力する関数 49 ?> 50 <ul> 51 <?php 52 foreach($comments as $msg) { 53 ?> 54 <li> 55 <div> 56 <span><?php echo $msg['name']; ?> 57 <?php 58 if(preg_match('/(管理人)/i', $msg['name'])){ 59 } else { 60 echo 'さん'; 61 } 62 ?> 63 </span> 64 <span>(ID:<?php echo $msg['id']; ?>)</span> 65 <span>date:<?php echo $msg['time']; ?></span> 66 </div> 67 <p> 68 <?php echo $msg['message']; ?> 69 </p> 70 <?php } 71 ?> 72 </li> 73 <?php 74 } 75 ?> 76 </ul> 77 </aside> 78 </div> 79</body> 80</html>
comments.php
php
1<?php 2// HTMLを出力する前にsession_start();しておいて下さい 3// ID生成にsession_id()を使います 4// 以下をPHPファイルに直接埋め込むか別ファイルに記述しておきrequire()やinclude()で呼び出して下さい 5 6// このPHPファイルをrequireした呼び出し元のディレクトリとファイル名を取得する 7// 直接埋め込む場合は"$r_buff[0]['file']"を"__FILE__"に置き換えて下さい 8$r_buff = @debug_backtrace(); 9if(isset($r_buff[0])){ 10 $r_name = preg_replace('/.php\z/', '.dat', $r_buff[0]['file']); 11} else{ 12 $r_name = false; 13} 14// コメントを取得する 15if($r_name){ 16 if(file_exists($r_name)){ 17 $comments = json_decode(file_get_contents($r_name), true); 18 } else{ 19 $comments = array(); 20 } 21} 22// 最後の10件だけ表示する 23// $comments = array_slice($comments , 0, 10); 24?>
xhr_comment_send.php
php
1<?php 2// 任意のディレクトリに置く 3// 上記JavascriptからこのファイルにPOST送信する 4$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null; 5$referer = preg_replace('/[?#][\s\S]*\z/', '', $referer); 6/* if(!preg_match('/http?://[\w/:%#$&?()~.=+\-]+/', $referer)){ 7// 他ドメインからのアクセスは拒否する 8exit("Bad Request!!"); 9} */ 10// POSTメソッドじゃなかったら終了 11if($_SERVER['REQUEST_METHOD'] !== 'POST'){ 12exit('Failed getting POST data.'); 13} 14// TOPページのURL 15// "index.html"などのファイル名は書かない 16$top_url = 'http://xxx.jp/'; 17// このファイルからTOPページがあるディレクトリまでの相対パス 18$top_path = '../../'; 19// 書き出しファイルを呼び出し元から取得する 20// 出力先は表示ページと同じディレクトリの同じ名前で拡張子が".dat" 21$buff = explode('/', (__DIR__. '/')); 22$m = count(explode('../', $top_path)); 23array_splice($buff, (0 - $m)); 24$input = implode('/', $buff). '/'. str_replace($top_url, '', $referer); 25$output = preg_replace('/.php\z/', '.dat', $input); 26// 現状のデータを読み込む 27if(file_exists($output)){ 28 $data = @json_decode(@file_get_contents($output), true); 29} else { 30 $data = array(); 31} 32/* 33if(!is_array($data)){ 34exit('Failed loading current data.'); 35} 36*/ 37// POSTデータを取得する 38$p_data = array(); 39foreach($_POST as $k => $v){ 40switch($k){ 41case 'name': 42case 'message': 43 // タグを全て削除 44 $p_data[$k] = preg_replace('/<[^>]*>/', '', $v); 45 // 改行を全て<BR>に置き換える 46 $p_data[$k] = preg_replace('/\n/', '<BR>', $p_data[$k]); 47break; 48case 'id': 49// IDが英数字6文字であることを確認する 50if(!preg_match('/\A[a-z0-9]{6}\z/', $v)){ 51 exit('Failed getting ID code.'); 52} 53 $p_data[$k] = $v; 54} 55} 56// サニタイズ 57//$p_data['name'] = htmlspecialchars( $msg['name'], ENT_QUOTES); 58//$p_data['message'] = htmlspecialchars( $msg['message'], ENT_QUOTES); 59// 名前に"管理"や"admin","root"といった文字が含まれた場合は名前を削除する 60$p_data['name'] = mb_convert_kana($p_data['name'], 'a'); 61if(preg_match('/(管理|admin|root)/i', $p_data['name'])){ 62 $p_data['name'] = ''; 63} 64// コメント内容が空でないことを確認する 65if(empty(preg_replace('/(\s|\n|\r|<BR>)/', '', $p_data['message']))){ 66exit('Failed getting comment.'); 67} 68if(empty(preg_replace('/(\s|\n|\r|<BR>)/', '', $p_data['name']))){ 69 exit('Failed getting name'); 70} 71 72// 同じIDが短時間でアクセスしていないか確認する 73if(isset($data)) { 74 if(strtotime('now') - strtotime($data[0]['time']) < 60){ 75 exit('Failed sending comment.'); 76 } 77} 78// コメントを配列に追加する 79array_unshift($data, array_merge($p_data, array('time' => date('Y-m-d H:i:s'), 'ip' => $_SERVER['REMOTE_ADDR']))); 80// ファイルに出力する 81$result = file_put_contents($output, json_encode($data), LOCK_EX); 82// 結果を返す 83if($result === false){ 84exit('Failed writing file.'); 85} else{ 86// 管理者にメールを送信する 87send__mail('xxx', 'xxx@jp', '', '', 'xxx@icloud.com', '', 'ブログにコメントされました', str_replace('<BR>', "\n", $data[0]['message']). "\n\n{$referer}#show_comments"); 88// HTMLをJavascriptに返す 89echo comment_html($data[0]); 90// ここ! 91 exit; 92} 93////////// 94/* 関数 */ 95////////// 96// メール送信の処理関数 97// 戻り値は送信受付可否(true/false) 98function send__mail($to_name, $to_address, $cc, $bcc, $from, $reply, $title, $body){ 99// 文字コード変換 100// 文字コードは"ISO-2022-JP"(S-JIS)に変換する 101$to = mb_convert_encoding($to_address, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 102$cc = mb_convert_encoding($cc, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 103$bcc = mb_convert_encoding($bcc, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 104$from = mb_convert_encoding($from, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 105$title = mb_convert_encoding($title, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 106$body = mb_convert_encoding($body, 'ISO-2022-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 107// 件名に日本語が使えるようにエンコードする 108// (mb_send_mailを使わずにmailを使う為) 109$title = '=?iso-2022-jp?B?'. base64_encode($title). '?='; 110// 送信情報の成形 111$send_to = mb_encode_mimeheader($to_name, 'ISO-2022-JP'). "<$to>"; 112$headers = array(); 113$headers[] = 'From: '. $from; 114$headers[] = 'Cc: '. $cc; 115$headers[] = 'Bcc: '. $bcc; 116$headers[] = 'Reply-To: '. $reply; 117$headers[] = 'Return-Path: '. $reply; 118$headers[] = 'Content-Type: text/plain; charset=ISO-2022-JP'; 119// $headers[] = 'Message-Id: <'. md5(uniqid(microtime())). '@web.analogstd.com>'; 120$headers[] = 'X-Mailer: PHP/'. phpversion(); 121$pfrom = '-f $from'; 122$smresult = mail($send_to, $title, $body, implode("\n", $headers), $pfrom); 123return $smresult; 124} 125function comment_html($msg){ 126 ob_start(); // 標準出力のバッファ開始 127 // <li>~</li>の中身を出力する 128?> 129<div> 130 <span><?php echo $msg['name']; ?> 131 <?php 132 if(preg_match('/(管理人)/i', $msg['name'])){ 133 } else { 134 echo 'さん'; 135 } 136?> 137 </span> 138 <span>(ID:<?php echo $msg['id']; ?>)</span> 139 <span>date:<?php echo $msg['time']; ?></span> 140</div> 141<p> 142 <?php echo $msg['message']; ?> 143</p> 144<?php 145 $html = ob_get_contents(); 146 ob_end_clean(); // バッファここまで 147 // 出力するHTMLを返す 148 return $html; 149} 150?>
試したこと
// ここ!と記述のある所に
php
1$r_buff = @debug_backtrace(); 2$r_name = preg_replace('/.php\z/', '.php', $r_buff[0]['file']); 3header("Location: $r_name");
と書いたら遷移しませんでした。
サニタイズをするにはどうすればいいですか。助けてくださいお願いします。
補足情報(FW/ツールのバージョンなど)
firefox最新版、safari604.1
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー