phpな休日 BBS sitemap
1. 順番に表示するためには順番に書き込む

(復習から入ります) 既出の処理ですが 〔予定〕 のログを例にします。
ログファイルに 〔予定〕 を書き込んでいく場合、最も多用する表示順に書き込んでいくようにします。(これが最も無理がない)
例えば

4<>20061111<>2006<>11<>11<>社員旅行<>
3<>20061025<>2006<>10<>25<>給料日<>
2<>20061001<>2006<>10<>1<>高崎・榛名合併<>
1<>20060925<>2006<>9<>25<>給料日<>

順に書き込んできた上記のようなログ(数字の意味は年月日です)に

5<>20061015<>2006<>10<>15<>森を散策<>

を書き足す場合、日付順でいくと真ん中に書き込むようにすれば、表示の時には上から走査して 〔新しいものが上〕 になり、下から走査すれば 〔古いものが上〕 になります。

書き込む時は2つ目の項目(上記例でいえば20061111の列)をたよりに上から走査していき、既存の〔項目2〕が新しく書き込む〔項目2〕より小さな値だったらそこに書き込むようにします。
この場合ですと新規に書き込む行の中で目安とするのが20061015で書き込む場所の目安となるのが20061001です。

$data = file("./plan.cgi"); //ファイルを開いて
$writeline = "5<>20061015<>2006<>10<>15<>森散策<>¥n"; //新しく追加するデータ
$dno = 20061015;
for ($i = 0; $i < count($data); $i++) { //走査する
$list = explode("<>", $data[$i]); //区切り文字 <> で区切る
if ($dno > $list[1]) {
array_splice($data, $i, 0, $writeline); //新しい行をここに挿入
break;
}
}

実際には最下行に追加する場合も考えなくてはならないので

$data = file("./plan.cgi"); //ファイルを開いて
$writeline = "5<>20061015<>2006<>10<>15<>森散策<>¥n"; //新しく追加するデータ
$dno = 20061015;
for ($i = 0; $i < count($data); $i++) { //走査する
$list = explode("<>", $data[$i]); //区切り文字 <> で区切る
if ($dno > $list[1]) {
array_splice($data, $i, 0, $writeline); //新しい行をここに挿入
$insert = "ok"; //挿入が済んだ印
break;
}
}
if (!isset($insert)) { //挿入が済んでいない(次の行がない=最下行であるということ)の場合
array_push($data, $writeline); //新しい行を最下行に挿入
}

このようになります。

2. ログを上から順に表示する

これも既出ですが、まずは普通にログファイルを読み込んで全行表示します。日付の新しい記事から表示します。
ログファイル(plan.cgi)の内容は

4<>20061111<>2006<>11<>11<>社員旅行<>
3<>20061025<>2006<>10<>25<>給料日<>
5<>20061015<>2006<>10<>15<>森を散策<>
2<>20061001<>2006<>10<>01<>高崎・榛名合併<>
1<>20060925<>2006<>9<>25<>給料日<>

こうなっています。先頭の項目(1~5)は書き込んだ順番です。

$data = file("./plan.cgi"); //ファイルを開いて
for($i=0; $i<count($data); $i++) { //1行づつ走査しながら表示します
$list = explode("<>",$data[$i]); //区切り文字 <> で区切る
print "id:" . $list[0] . " ";
print "dno:" . $list[1] . " ";
print $list[2] . "年";
print $list[3] . "月";
print $list[4] . "日 ";
print "予定:" . $list[5] . "<br>¥n";
print "<hr>";
}

このへんは問題ないでしょうか。

実行
3. ログを下から逆順に表示する

日付順のログに限りませんが逆走査して表示したい場面もあります。
前出のログファイル(plan.cgi)を、日付の古い順に表示するには

$data = file("./plan.cgi"); //ファイルを開いて
for ($i = count($data)-1; $i >= 0; $i--) { //最下行から1行づつ走査しながら表示します
$list = explode("<>",$data[$i]);
print "id:" . $list[0] . " ";
print "dno:" . $list[1] . " ";
print $list[2] . "年";
print $list[3] . "月";
print $list[4] . "日 ";
print "予定:" . $list[5] . "<br>¥n";
print "<hr>";
}

違うのは赤文字部分だけです。

実行
4. 書込順にソートしてから表示

ログを書き込んだ順(逆も)に表示したい場合もあります。
今回はログを日付順になるように書いているので、書込順にするためには先頭の項目(1~5)の列をソートします。

$data = file("./plan.cgi"); //ファイルを配列に読み込む
for ($i = 0, $z = count($data); $i < $z; $i++) { //列を分解して二次元配列にする
$data[$i] = explode("<>", $data[$i]); //区切り文字 <> で区切る
}
function psort($a, $b) { //ユーザー定義関数
$pcmp = strnatcmp($a[0], $b[0]); //自然順で比較
return $pcmp;
}
usort ($data, "psort"); //ソート
for ($i = count($data)-1; $i >= 0; $i--) { //最下行から1行づつ走査しながら表示します
print "id:" . $data[$i][0] . " dno:" . $data[$i][1] . " " . $data[$i][2] . "年" . $data[$i][3] . "月" . $data[$i][4] . "日 " . $data[$i][5] . "<br>¥n";
<hr>
}

二次元配列をソートするには function psort() というようにユーザー定義関数を作成します。 psort が作成した関数名です。
ユーザー定義関数を使用してソートする場合の関数が usort です。
比較は strnatcmp関数で。strcmpでもこの場合、結果は同じですが、比較する数値の桁が違う場合はうまくいきません。

実行


Fatal error: Uncaught Error: Undefined constant "Y.n.j" in /home/users/2/secret.jp-final/web/phpholiday/28/index.cgi:160 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/28/index.cgi on line 160