PHP操作超大日志文件
php工程师的晋级不仅仅是一个curd boy,你还需要懂得更多计算机基础知识。
如图我生成一个15g的日志文件,其中字段为$uid\t支付时间\t支付金额


其实整体的思路就是,在做开发时需要有使用内存的概念,因为每一台服务器的php允许使用的内存都是既定的,那么在这种情况下来讲,我们的php脚本所占用内存是坚决不能超出php.ini设置的memory_limit,那么如果我们想解析读取操作一串大的文件怎么办?
譬如php的内存只有2g,但是我们需要操作一个15g的文件?我们有方法么?
当然有,我们只需要在内存占用允许的情况下,一次性把buffer打满之后进行后续业务操作。或者逐行读取(效率坡低)都可以满足在有限内存的情况下去读取大文件。
那么废话不多说,直接上代码。
<?php
declare(strict_types = 1);
function writeLog(string $path = '')
{
if (!file_exists($path)) {
throw new Exception('文件不存在');
}
if (!is_writable($path)) {
throw new Exception('文件不可写');
}
$obj = new SplFileObject($path, 'w');
//500000000
$msg = '';
for ($i = 1; $i <500000000; $i++) {
$uid = $i%100000;
$msg .= $uid.'\t2019-10-18 10:00:11\t2000'.PHP_EOL;
if (($i % 50000) == 0) {
$obj->fwrite($msg);
$msg = '';
}
}
}
function readLog(string $path = '')
{
ini_set('memory_limit', '2G');
if (!file_exists($path)) {
throw new Exception('文件不存在'.$path);
}
if (!is_readable($path)) {
throw new Exception('文件不可读'.$path);
}
$begin = microtime(true);
$fp = fopen($path, 'r');
while (!feof($fp)) {
fread($fp, 38000000);
}
fclose($fp);
$end = microtime(true);
echo "cost : ".( $end - $begin ).' sec'.PHP_EOL;
exit('ok');
}
$path = __DIR__.'/payment.log';
//初始化日志文件
//writeLog($path);
readLog($path);