返信投稿があった場合は、ログファイルの途中に1行挿入する形になります。あるいは最下行を追加するケースもあります。最下行の場合は
array_push(今までのデータ, 追加する行のデータ);
と書きます。途中に挿入する場合は
array_splice(今までのデータ, 挿入場所, 0, 挿入する行のデータ);
と書きます。
また、私とsakuraさんのログを例に出しますと
5<>5<>haku<>email<>http://www.p-ho.net/<>title3<>comment3<>time<>iphost<>
6<>5<>sakura<>email<><>Re:title3<>response3<>time<>iphost<>
3<>3<>haku<>email<>http://www.p-ho.net/<>title2<>comment2<>time<>iphost<>
4<>3<>sakura<>email<><>Re:title2<>response2<>time<>iphost<>
1<>1<>haku<>email<>http://www.p-ho.net/<>title1<>comment1<>time<>iphost<>
2<>1<>sakura<>email<><>Re:title1<>response1<>time<>iphost<>
[項目1] の数字が書き込まれた順番です。この状態で上から3行目の親記事に返信する場合、すでに返信がひとつついていますので [記事番号4] の下に [記事番号7] として書き込まれるようにします。
【[記事番号1] の上に [記事番号7] として書き込まれるようにします。】というほうが処理のイメージです。
5<>5<>haku<>email<>http://www.p-ho.net/<>title3<>comment3<>time<>iphost<>
6<>5<>sakura<>email<><>Re:title3<>response3<>time<>iphost<>
3<>3<>haku<>email<>http://www.p-ho.net/<>title2<>comment2<>time<>iphost<>
4<>3<>sakura<>email<><>Re:title2<>response2<>time<>iphost<>
7<>3<>haku<>email<>http://www.p-ho.net/<>Re:title2<>comment2<>time<>iphost<>
1<>1<>haku<>email<>http://www.p-ho.net/<>title1<>comment1<>time<>iphost<>
2<>1<>sakura<>email<><>Re:title1<>response1<>time<>iphost<>
上記の赤文字行を追加するために、まず返信用フォームからPOSTで受け取った bbsresno(3) を探します。3 が見つかったら、見つかったという印($insert = 1)をつけて今度は [項目2] を走査しながら、3 でなくなる行(次のスレッド)を探します。見つかったらそこに新たな行を挿入します。
次のスレッドが見つからなかった場合は、そのスレッドが最終スレッドであるということなので、ログの最後に行を追加します。
$insert = 0; //$bbsresno と $list[0] が同一の行(親記事)を探す
for ($i = 0; $i < count($data); $i++) { //走査する
$list = explode("<>", $data[$i]); //区切り文字 <> で区切る
if ($insert == 0) { //まだ親記事が見つかっていない
if ($bbsresno == $list[0]) { //ここが親記事
$insert = 1; //親記事を見つけた印
}
}
else { //レス記事は飛ばして
if ($bbsresno != $list[1]) { //次の親記事まできたら
array_splice($data, $i, 0, $reswrite); //新しい行をここに挿入
$insert = 0; //挿入が済んだ印
break;
}
}
}
if ($insert == 1) {array_push($data, $reswrite);} //挿入が済んでいない(次の親記事がない=最下行であるということ)の場合
返信投稿があったスレッドをログの一番上に移動します。
ログを走査していって、目的のスレッドを見つけたらカウントを始めます。目的のスレッドが何行目から始まって、何行になるかを確認したら
array_splice($data, 上からの行数, スレッドの行数)
でスレッドごと削除。削除した内容を $string 変数に代入しておいて
array_merge($string, $data)
と先頭に追加する形で移動します。
$linecount = 0; //行数カウント
for ($i = 0; $i < count($data); $i++) { //走査する
$list = explode("<>", $data[$i]); //区切り文字 <> で区切る
if ($bbsresno == $list[0]) { //$bbsresnoを頼りに親記事を探す
$top = $i; //上からの行数
$linecount++; //行数をプラス
}
elseif ($bbsresno == $list[1]) {
$linecount++; //行数をプラス
}
}
if (isset($linecount)) {
$string = array_splice($data, $top, $linecount); //移動する行を削除
$newdata = array_merge($string, $data); //先頭に足す
}
$redata = fopen("./bbslog.cgi", "w"); //書き込みモードでファイルを開く
flock($redata, LOCK_EX); //ファイルロック
foreach($newdata as $value) { //配列処理して
fputs($redata, $value);} //書き込む
flock($redata, LOCK_UN); //ファイルロック解除
fclose($redata); //ファイルを閉じる
ここまでの全体の流れをざっと明記しておきます。
if (レスフォームナンバーが送られてきた場合) {
レスフォーム表示
}(レスフォームナンバーが送られてきた場合終わり)
else {(レスフォームナンバーが送られてきた場合以外)
//新規投稿・レス投稿共通処理
if (POSTに name か comment があれば) {
受け取り処理をする、ログを走査して新投稿の記事番号を決める
if (URLが書かれていた場合は) {//処理を飛ばす
if (多重投稿の場合は) {//処理を飛ばす
//共通処理ここまで
if (返信投稿の場合) {
処理をする
}
else {//新規投稿の場合
処理をする
}
}//投稿受け取り処理終わり
}//多重投稿の場合はここまで飛ばす
}//URLが書かれていた場合はここまで飛ばす
//最初の表示・新規投稿処理後の表示・レス投稿処理後の表示
}//レスフォームナンバーが送られてきた場合以外終わり)
Fatal error: Uncaught Error: Undefined constant "Y.n.j" in /home/users/2/secret.jp-final/web/phpholiday/19/index.cgi:146 Stack trace: #0 /home/users/2/secret.jp-final/web/phpholiday/index.php(334): include() #1 {main} thrown in /home/users/2/secret.jp-final/web/phpholiday/19/index.cgi on line 146