dポイントプレゼントキャンペーン実施中!

初めて質問を投稿させて頂きます。
現在PHPを勉強中なのですが、ファイルへの書き込み、読み込み方法はわかったのですが、1行づつ書き込みして行き、
「ファイルの中身が特定行数を超えた場合に古い行から削除する」
という処理をしたいと思っています。
このような事をしたい場合、どのような処理をすればよいのでしょうか?

ご存知の方いらっしゃいましたらお知恵を貸して頂けましたら幸いです。

A 回答 (3件)

その後、「w」モードでのflock関数の使い方について心配でしたので、調べてみたら、


「w」モードでflockが聞かないことがわかりましたので、書きなおしました。

<?php
$new_line = 'これが新しい行'."\r\n";

//ファイルを全て読み出し
$data = file('log.csv'); //file関数は改行ごとに配列に分解して取得出来ます。
$data[] = $new_line; //配列に新しい行を追加

$lines = count($data); //現在の行数を取得

//まず指定行数以上達しているのかどうかを判別
if($lines >= 20){ //指定行が100件だとして、それ以上存在するなら、一番古いもの(配列の一番先頭)を削除
unset($data[0]);
}

//全部の行をファイルに書き込み
$fp = fopen('log.csv', 'a+');
if(flock($fp, LOCK_EX)){
ftruncate($fp, 0); //ファイルを0バイトにする
foreach($data as $datum){
fwrite($fp, $datum);
}
}else{
echo "ファイルをロックできません。";
}

fclose($fp);

?>

また、参考にさせていただいたサイトを貼りつけておきます。
失礼しました。

参考URL:http://www.programming-magic.com/20080211020413/
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
丁寧にソースまでつけて頂き大変わかりやすく、助かりました。
データベースについても難しそうですが今後勉強していこうと考えております。
ありがとうございましたm(_ _)m

お礼日時:2010/01/03 12:31

もしそれが本当に「ログファイル」であれば、一行追加しながら一行削除する


というのは無駄なので現実的ではありません。
ログファイルというのはローテートして使用するものです。
syslogdなどでサイズや期間を指定してまわしてください。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
「削除せずに残す」というやり方もあるのですね。
現在はWEBチャットを作成中でそのログが過去に遡って蓄積されていくのはあまり気持ちよく無いので1行毎に削除するという形が良いかななどと思ったのですが、例えば掲示板やアクセスログなどの場合には「ログには残す」形で「出力しない」という方法を取るのが良いかもしれないと思いました。
まだやり方などが想像つかないので先の課題になりそうですが・・・。

ありがとうございましたm(_ _)m

お礼日時:2010/01/03 12:51

基本的にfopen関数などでファイルを開く場合、指定行数を削除するとか、そういうことは出来ないと思います。



なので、一度全部の行を取得した後に、指定行数分のみ上書きで書き込む、という方法になると思います。

<?php
$new_line = 'これが新しい行'."\r\n";

//ファイルを全て読み出し
$data = file('log.csv'); //file関数は改行ごとに配列に分解して取得出来ます。
$data[] = $new_line; //配列に新しい行を追加

$lines = count($data); //現在の行数を取得

//まず指定行数以上達しているのかどうかを判別
if($lines >= 100){ //指定行が100件だとして、それ以上存在するなら、一番古いもの(配列の一番先頭)を削除
unset($data[0]);
}

//全部の行をファイルに書き込み
$fp = fopen('log.csv', "w");
flock($fp, LOCK_EX); //ファイルを排他ロック

foreach($data as $datum){ //配列を一行ずつ展開して
fwrite($fp, $datum); //書き込み
}

fclose($fp); //ファイルを閉じる

?>

といった感じで、一応は実装出来ます。
ただし、

・全てのデータを取得して配列に落としている
・「w」モードでファイルを開いているので、ファイルのロックに失敗したとか、何らかの原因で全データがなくなったり破損したりするかもしれないので別の処理をかく必要もあるかもしれない。
・古い行意外にも途中の要らない行を削除するなどする場合はまた別のそれなりに面倒な記述が必要になる。

と、処理が重かったり、ある程度リスクがあったりするので、
ただファイルを記録するよりかは、何らかのデータベースをご利用された方が良いです。
早いうちにMySQLとかSQLiteあたりはいじってみてください。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
hogehoge78様に追加で頂いたアドバイス(回答No2)のほうにお礼の方まとめさせて頂きましたm(_ _)m

お礼日時:2010/01/03 12:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!