php通过yield读取大文件

2020-02-17 09:18:56


yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。 在读取大型日志文件的时候file_get_content把整个文件读入一个字符串中,这将导致内存占用过高,并且读取的文件越大耗时越高。 这时候就可以通过php的yield来实现一行一行读取,提高性能的同时大幅降低内存占用。

public static function getLines($file, $len=1024){
	$f = @fopen($file, 'r');   //加上@符号忽略报错信息
	if(!$f){
		//读取失败返回空数组
		return [];
	}
	try {
		//$len为读取的字节数, 默认为1024字节
		while(true){
			$line = fgets($f, $len);
			if(empty($line)){
				break;
			}
			yield $line;
		}
	} finally {
		//最后关闭文件
		fclose($f);
	}
}

/**
 * 使用示例
 */
public function example(){
	 $file = "/var/logs/tmp.log";
	 foreach(self::getLines($file, 65536) as $n=>$line){
		 echo $line;
	 }
}