• ベストアンサー

ログファイルが一定行数を超えたら削除する方法

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

  • PHP
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

その後、「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/
studyphp
質問者

お礼

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

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

もしそれが本当に「ログファイル」であれば、一行追加しながら一行削除する というのは無駄なので現実的ではありません。 ログファイルというのはローテートして使用するものです。 syslogdなどでサイズや期間を指定してまわしてください。

studyphp
質問者

お礼

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

回答No.1

基本的に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あたりはいじってみてください。

studyphp
質問者

お礼

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

関連するQ&A

  • C#でファイルに書き込める行数を制限する

    現在、C#でコンソールアプリを開発しています。 そのアプリのログをファイルに保存しているのですが、そのファイルの行数が500行を超えないようにすることはできるでしょうか? 要件としては ・指定した名称のファイルがあれば、その末尾に追記 ・指定した名称のファイルがなければ、新規作成する ・501行目をファイルに書き込むとき、1行目は削除され、ファイルの末尾に501行目が書き込まれる という感じです。 どうか、お知恵をかしてください。

  • 【PHP】 記事の削除について(ログの一部を削除)

    log.txt ファイル の中身が下の様になっていた場合、削除したい記事番号を選び削除キーを押したら 選んだ記事番号の記事を削除するにはどうしたらよいでしょうか? ◆ log.txtファイルの中身 1 あああ君 おはよう ・ 3 かかか君 良い天気ですね ・ ・ 6 そそそ君 明日は晴れるでしょ ※ 記事番号($no) 名前($name) 内容($body)と配列がなっています。(全角の空白で区切ってます) ◆ 削除したい記事番号を選ぶ所のファイル名は 「file01.php」 としています。   「file01.php」では次ぎの様に削除キーを設定しています。 <table><tr><td> <form name="form" action="file02.php" method="POST"> <input type="text" name="delkey" size="8"> <input name="Submits" type="submit" value="削除"></form> </td></tr></table> ◆ 「file01.php」からのデーターの受け取りファイル名は 「file02.php」としています。   「file02.php」では次ぎの様にしてデーターを受け取る様にしています。 <?php $delkey = $_REQUEST["delkey"]; $data = file("log.txt"); for($i=0; $i<sizeof($data); $i++){ list($no,$name,$body) = explode( " " , $data[$i]); if($no == $delkey){ //・・・記事削除処理 } } ・ ・ ・ ?> ◆ 書込みは次ぎの様にしています。 $fp = fopen("log.txt","w"); $ndata = implode( " " , array($no,$name,$body."\n") ); fputs($fp,$ndata); fclose($fp); ここまではやってみましたが、ここから、どのような仕組みで選んだ記事番号の記事を削除したらよいのか分らないので教えて下さい? また、記事削除の処理をした場合、ログファイルを元のと書きかえるいはどうしたらよいのでしょうか教えて下さい? 例えば、選んだ削除番号が「3」だった場合など・・・記事削除処理のところはどうしたらよいのでしょうか? if の所では、記事番号($no)が選んだ削除したい記事番号($delkey)と等しいなら、・・・記事削除処理 と言う様にしています。 記事削除処理のところは、記事削除の仕組み仕方が分らないので空白となっています。 以上、出来れば詳しく教えて頂けると助かります。宜しくお願い致します。

    • ベストアンサー
    • PHP
  • ファイルの中の行数を確認して、減らす

    今phpで掲示板を作っている初心者ですが、 ファイルの中の行数を確認してから、 ある一定数をオーバーしたら古いものからけしていく作業を したいのですが、上手く行きません。 ファイルの行数を確認する方法は、 $count=0; $fd=fopen("$filename","r"); while(!feof($fd)){ $data = fgets($fd); $count++; } な感じで、whileしか無理ですかね? この方法だとデータが多くなると心配です。 何かもっと良い方法はないでしょうか? また上で行数を調べて、例えば行数が100件を越したら一行消し、 それを再度ファイルに書き込むにはどうしたらよいのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • pythonでファイルのコメント行を削除したい

    pythonを勉強し始めたばかりなのですが、ちょっと困っています。 pythonでデータファイルのコメント行を削除して、データだけ後の計算に回したいのですが、コメント行を削除する方法がわからなくて困っています。 データファイルは以下のようになっています。 #test1 #test2 test2 #test3 teset3 test3 0, 10 1, 2 2, 9 3, 3 4, 4 5, 7 コメント行は頭に#が付くようになっていますが、この例のように3行ではなく、他の行数になった場合でも対処できるようにしたいです。

  • ファイルから指定行数分だけ読み込む

    あるファイルに下記のようにタブで区切られた、ログのようなファイルがあった場合。 aaa test 1 bbb test 2 ccc test 3   ・   ・   ・ このログの1行目~30行目まで1行ずつGETしたい場合や、30行目~60行目までGETしたい場合はどのようにしたらいいのでしょうか?? 30行ずつ配列にいれこんだあとに、表示させようと思ったのですが、手間がかかりそうなので。。 grepでもこのように行数を指定できるやり方があればいいのですが。。。

    • ベストアンサー
    • PHP
  • Excel2010である特定の行を削除する方法

    現在エクセル2010を用いて、アンケートの集計を行っています。 その中である特定の行だけを削除したいのですが、どのようにすればよいのか分かりません。 具体的には、以下のようなデータがあったときに、年と組と番号が重複しているデータの行をすべて削除したいのです。 年 組 番号 問1 問2 問3 1 1 01 2 2 2 1 2 21 1 3 2 1 3 24 3 2 1 1 2 21 1 3 2 というデータがあった場合には、1年2組の番号21の人が重複しており、そのデータを数えたくないので、 その行(問1~3まですべて)を削除したいのです。 このような時はどのような処理を行えばよろしいのでしょうか? どなたかご存知の方いらっしゃいましたら教えていただけると幸いです。

  • gccコンパイラのプログラムでファイルの特定行削除をしたい

    初心者な質問で申し訳ありません。。 Linuxでプログラムの勉強をしています。 その中でファイルにデータを書込み、 あとでそこを検索してその行を削除するというプログラムを作成しており、そのためのCの関数リファレンスやいくつか書籍を調べてみたのですが、 ファイルから特定の行を削除するという具体的な方法を見つけることができませんでした。 今のところ現実的なのは 1.特定の行より前の行までを別のファイルに書き出し。(コピー) 2.特定の行より後ろの行以降を別のファイルに書き出し(コピー) 3.コピー元のファイルを削除する。 4.コピーしたファイルを3.で削除した名前に変える。 なのですが、これ以外の方法をご存知の方、御教授いただけますでしょうか? なお、Qtの勉強もかねてなのでコンパイラはgcc限定としております。

  • ファイルの中の特定の行だけを削除したい

    あるファイルの特定の行だけを削除したいのですが、高速に行う方法はありませんか? とあるファイルがあり、これは数行~数万行にも及ぶ可能性のある大規模なファイルです。 このファイルの、特定の行を検索してその行だけ削除し、空いてしまった行は詰めたいのですが、どのようにすれば高速に行えますか? かなり遅い方法だと、 xxx = "hoge\n" arr = [] f = open("file") f.each{|line| if line != xxx then arr<<line end } f.close open("file", "w").puts arr.join() などが考えられるのですが、遅すぎて使えないはずです。 速度が求められる処理のため、困ってます。 もしご存じの方がいらっしゃいましたら、教えて頂けませんか?

    • ベストアンサー
    • Ruby
  • エクセル2007にて文字の入った行数を数える方法

    行き詰まってしまったので、こちらで質問させてください。 例なのですが Q1~3、Q4~6各設問の数値、文字が入った行を計算する場合 どのような数式を使えばいいでしょうか。 Q1~3 ○行 Q4~6 ○行 というふうに行数を計算したいのですが、お知恵をお貸しください。

  • データファイルの行を削除する

    掲示板のようなものを作っています。 データを、1投稿につき1行使って、項目を記号を使って分割させています。 1,こんにちは,umi,2004-4-1 みたいな感じですが、記事を1行削除するときの処理なのですが、 1,ファイルをロックして読み込み 2,削除する以外の行を$buffに入れる 3,rewindでポインタを先頭に 4,書き込み、ロック解除 のような処理をしているのですが、一番下の行に古いデータが残ってしまいます。 例えば 4,またあした,umi,2004-4-1 3,おはよう,umi,2004-4-1 2,さようなら,umi,2004-4-1 1,こんにちは,umi,2004-4-1 というデータの上から2行目を削除すると 4,またあした,umi,2004-4-1 2,さようなら,umi,2004-4-1 1,こんにちは,umi,2004-4-1 1,こんにちは,umi,2004-4-1 というふうになってしまいます。 通常、このような場合はどのように処理すればよろしいのでしょうか。 よろしくお願い致します。

    • ベストアンサー
    • PHP

専門家に質問してみよう