要件は次のとおりです: 約 500 万行の約 1G のログ ファイルがあり、php を使用して最後の数行の内容を返します。
1. file 関数を直接使用して操作しないと、file_get_content() が確実にメモリ オーバーフローを報告します
注: file 関数はすべてのコンテンツを一度にメモリに読み込むため、PHP は、不適切に作成されたプログラムの実行を防ぐために、メモリを消費しすぎるとシステム メモリが不足し、サーバーがクラッシュするため、デフォルトでは最大メモリ使用量は 16M に制限されます。この値が -1 に設定されている場合、これは php.ini のmemory_limit = 16M によって設定されます。メモリ使用量に制限はありません。
以下は、file を使用してこのファイルの最後の行を抽出するコードです。
コードをコピーします コードは次のとおりです:
ini_set('memory_limit','-1');
$file = 'access.log ';
$data = file($file);
$line = $data[count($data)-1];2. Linux tail コマンドを直接呼び出して、最後の数行を表示します。
Linux コマンドラインでは、tail -n 10 access.log を直接使用して、ログ ファイルの最後の数行を簡単に表示できます。次のように、php を直接使用して tail コマンドを呼び出し、php コードを実行できます。
コードをコピーします コードは次のとおりです:
file = 'access.log';
$file =escapeshellarg($file) // コマンドラインパラメータを安全にエスケープします
$line = `tail - n 1 $file`;
echo $line;3. php を直接使用する fseek は、ファイル操作を実行する最も一般的な方法であり、ファイルのすべての内容をメモリに読み取る必要はありませんが、ポインターを介して直接操作します。 fseek を使用してファイルを操作する場合の効率は非常に効率的です。 操作にはさまざまな方法があり、効率は若干異なる場合があります。一般的に使用される 2 つの方法を以下に示します。
方法 1:
最初に fseek を通じてファイルの最後の EOF を見つけ、次に最後の行の開始位置を見つけ、この行のデータを取得し、次に次の行の開始位置を見つけて、 $num 行が見つかるまで、この行の位置などを調べます。
コードをコピーします
コードは次のとおりです: function tail($fp,$n,$base=5){
assert($n>0);
$pos = $n+ 1;
$ Lines = array();
while(count($lines)< =$n){
try{
fseek($fp,-$pos,SEEK_END);
fseek(0 ); }
return array_slice($lines, 0,$n);
}
var_dump(tail(fopen("access.log","r+"),10));
方法 2:
引き続き fseek を使用するファイルの末尾から読み込みを開始しますが、今回はビットごとに読み取るのではなく、データを部分的に読み取るたびに、読み取ったデータが buf に配置され、その数が続きます。改行文字 (n) を使用して、最後の $num 行のデータが読み取られたかどうかを確認します。
実装コードは次のとおりです
コードをコピーします
コードは次のとおりです:
$fp = fopen($file, "r");$line = 10;$pos = -2 ;
$t = " " ;
$data = "";
while ($line > 0) { while ($t != "n") { fseek($fp, $pos, SEEK_END); $t = fgetc($fp } データメソッド 3:
コードをコピーします
コードは次のとおりです:
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = ( intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len $seekSize = ($max - $ len > $chunk) ? $chunk : $max - $len;
fseek($fp, ($len + $seekSize) * -1, SEEK_END);
$readData = fread($fp, $seekSize) 。 readData;
if (substr_count($readData, "n") >= $num + 1) {
preg_match("!(.*?n){".($num)."}$!", $ readData、$match)
readData, $match);
http://www.bkjia.com/PHPjc/328160.html
www.bkjia.com
true
http://www.bkjia.com/PHPjc/328160.html
技術記事要件は次のとおりです。 約 500 万行の約 1G のログ ファイルがあり、PHP を使用して最後の数行の内容を返します。 1. file 関数を直接使用して操作するか、file_get_content() が確実にレポートします...