php日志文件过大,php处理大的日志文件

php为了防止内存占用过多,在php.ini限制了内存占用,memory_limit = 16M默认为16M,可

以修改脚本占用内存限制,比如为-1,无限制。

做了如下实验。

场景:

一个1G左右的日志文件,大约700万行。

方案:

一、file函数直读。

代码如下

ini_set('memory_limit','-1');

$file = 'access.log';

$data = file($file);

$line = $data[count($data)-1];

echo $line;

机器直接无响应。。大概运行了200多秒。。

二、调用linux的tail函数

在linux命令行下,可以直接使用tail -n 10 access.log很轻易的显示日志文件某行。

file = 'access.log';

$file = escapeshellarg($file); // 对命令行参数进行安全转义

$line = `tail -n 1 $file`;

echo $line;

时间:0.0045秒,已经达到可用标准,但对环境有要求。

三、fseek函数

fseek函数不需要把文件全部装入内存,而是直接通过指针来操作,所以效率很高。代码:

$fp = fopen($file, "r");

$line = 10;

$pos = -2;

$t = " ";

$data = "";

while ($line > 0) {

while ($t != "\n") {

fseek($fp, $pos, SEEK_END);

$t = fgetc($fp);

$pos --;

}

$t = " ";

$data .= fgets($fp);

$line --;

}

fclose ($fp);

echo $data

时间:0.0105秒

再提升一点,按块读取,然后计算块内的\n标记来算到了多少行。

$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 = 0; $len < $max; $len += $chunk) {

$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);

$data = $match[0];

break;

}

}

fclose($fp);

echo $data;

时间:0.002秒

再快一点的话,可以判断如果行数大于一半,可以从后往前取,这样二分之后,取后面的速度会

更加快速。

function tail($fp,$n,$base=5)

{

assert($n>0);

$pos = $n+1;

$lines = array();

while(count($lines)< =$n){

try{

fseek($fp,-$pos,SEEK_END);

} catch (Exception $e){

fseek(0);

break;

}

$pos *= $base;

while(!feof($fp)){

array_unshift($lines,fgets($fp));

}

}

return array_slice($lines,0,$n);

}

var_dump(tail(fopen("access.log","r+"),10));

实际应用中再根据具体情况调整。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值