テキストファイルからすべてを読み取ってエコーしたい。ただし、読み取り中にテキストファイルにさらに多くの行が書き込まれる可能性があるため、ファイルの最後に達したときにスクリプトを終了させたくありません。これはphpで可能ですか?
4 に答える
これは単なる推測ですが、「tail -f」出力をパススルー (passthru) してみてください。
ただし、バッファを flush() する方法を見つける必要があります。
私見よりもはるかに優れた解決策は、ajax サイトを構築することです。
ファイルの内容を配列に読み込みます。セッションの行数を保存します。ファイルの内容を印刷します。
ファイルをチェックするスクリプトに対して x 秒ごとに ajax リクエストを開始します。行数が多い場合は、セッション数が結果をページに追加します。
挿入された popen() を使用できます。
$f = popen("tail -f /where/ever/your/file/is 2>&1", 'r');
while(!feof($f)) {
$buffer = fgets($f);
echo "$buffer\n";
flush();
sleep(1);
}
pclose($f)
スリープは重要です。スリープがなければ、100% の CPU 時間を使用できます。
また、次を使用することもできfilemtime
ます。最新の変更タイムスタンプを取得し、出力を送信し、最後に、保存されfilemtime
ているものを現在のものと再度比較します。
とにかく、ブラウザ(またはクライアント)と同時にスクリプトを実行する場合は、チャンク(fread
、flush
)を使用して出力を送信し、最後に変更を確認する必要があります。変更がある場合は、ファイルを再度開いて、最新の位置から読み取ります(のループの外側の位置を取得できますwhile(!feof())
)。
私はそれを解決しました。
トリックは fopen を使用し、eof に達したらカーソルを前の位置に移動し、そこから読み続けることでした。
<?php
$handle = fopen('text.txt', 'r');
$lastpos = 0;
while(true){
if (!feof($handle)){
echo fread($handle,8192);
flush();
$lastpos = ftell($handle);
}else{
fseek($handle,$lastpos);
}
}
?>
それでもかなりのCPUを消費しますが、それを解決する方法がわかりません。
実際、「エコー」すると、バッファに送られます。したがって、ブラウザがまだ出力を受信している間に追加された場合、新しいコンテンツを「追加」する必要があります。そして、これは不可能です (ただし、これにはいくつかのアプローチがあります)。