在php中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。
需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容。
实现方法:
1. 直接采用file函数来操作
注:由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的memory_limit = 16M来进行设置,这个值如果设置-1,则内存使用量不受限制.
下面是一段用file来取出这具文件最后一行的代码.
整个代码执行完成耗时 116.9613 (s).
$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;
我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了.
2.直接调用linux的tail命令来显示最后几行
在linux命令行下,可以直接使用tail -n 10 access.log很轻易的显示日志文件最后几行,可以直接用php来调用tail命令,执行php代码如下.
整个代码执行完成耗时 0.0034 (s)
file = 'access.log';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 1 $file`;
echo $line;
3. 直接使用php的fseek来进行文件操作
这种方式是最为普遍的方式,它不需要将文件的内容全部读入内存,而是直接通过指针来操作,所以效率是相当高效的.在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法.
方法一:
首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置,再取这一行的位置,依次类推,直到找到了$num行。
实现代码如下
整个代码执行完成耗时 0.0095 (s)
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));
方法二:
还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换行符(\n)的个数来判断是否已经读完最后$num行数据.
实现代码如下
整个代码执行完成耗时 0.0009(s).
$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.0003(s)
ini_set('memory_limit','-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data)-1];
echo $line;
来自http://blog.163.com/lgh_2002/blog/static/44017526201073101057824/
分享到:
相关推荐
### PHP读取数据库范例详解 #### 一、引言 在Web开发中,PHP(Hypertext Preprocessor)是一种广泛使用的开源服务器端脚本语言,特别适合于Web开发并可嵌入HTML中。PHP与数据库结合使用可以实现动态网站的各种功能...
在处理PHP超大文件下载时,通常会遇到内存溢出的问题,这是因为下载大文件时,PHP需要一次性读取整个文件到内存中,导致内存消耗过大而溢出。为了防止这种情况,一个有效的解决方案是实施断点续传下载机制。断点续传...
【FCKeditor 使用方法详解】 FCKeditor 是一个基于JavaScript的开源富文本编辑器,它在Web开发领域中被广泛使用,尤其适用于那些需要提供用户友好、可视化的文本编辑功能的网站。FCKeditor 具备强大的功能,包括...
在PHP中,处理zip文件是一项常见...总之,PHP通过`ZipArchive`类提供了强大的工具来处理zip文件,无论是读取、修改还是创建,都能满足大多数开发需求。了解和熟练掌握这些方法,将有助于在项目中更有效地处理压缩文件。
### PHP中CURL相关函数详解 #### 一、概述 CURL(Client URL)是PHP中用于处理HTTP请求的强大库之一,它支持多种协议(如HTTP、HTTPS、FTP等),并能够实现各种复杂的网络交互需求。本文将详细介绍PHP中与CURL相关...
总的来说,PHP DIYUpload结合WebUploader提供了一种高效、可靠的图片批量上传解决方案,通过前端分片上传和后端合并文件的策略,有效解决了大文件上传和并发上传的问题。开发者可以根据自身项目需求,对这个方案进行...
【PHP+HTML5上传技术详解】 在Web开发中,文件上传功能是不可或缺的一部分,而PHP作为后端服务器语言,与HTML5的结合可以提供更高效、用户体验更好的上传方式。本示例"PHP+Html5上传demo带预览、进度条"就是这样一...
### PHP+MySQL留言板系统知识点详解 #### 一、系统概述 **PHP+MySQL留言板系统**是一种常见的Web应用程序,用户可以在其中留下评论或消息。该系统主要包括以下几个核心功能:提交留言、展示留言、编辑留言以及删除...
### PHP复习知识点详解 #### 文件上传操作 在PHP中,文件上传是一项常见需求,尤其是在处理CSV等文件格式时。从给定的部分内容中可以看出,这是一个简单的文件上传表单及后端处理逻辑。 **HTML表单代码** ```...
【PHP SOCKET编程详解】 在PHP中,SOCKET编程允许开发者创建网络通信协议,实现服务器与客户端之间的数据交换。虽然PHP通常被用作Web开发的脚本语言,但其socket模块的功能强大,能够处理多种网络任务,如FTP列表、...
**PHP网站小案例详解** PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适合于Web开发,能够嵌入到HTML中使用。在这个“PHP网站小案例”中,我们将探讨如何利用PHP构建一个基础的Web应用程序,这...
此外,还可以使用`copy()`函数、`file_get_contents()`函数和其他相关函数对文件进行读取、处理和存储,从而实现更丰富的文件操作功能。 总之,`PHP`的`$_FILES`函数是处理文件上传的关键工具,提供了全面的信息以...
例如,`verifyRespondSign` 函数演示了如何使用从PEM文件中读取的公钥来验证签名: ```php function verifyRespondSign($data, $signature) { $filePath = 'allinpay-pds.pem'; $cert = file_get_contents($...
- 若要持久存储用户信息,应将数据存入数据库,然后在需要时再从数据库中读取。 - 避免在Session中存储敏感信息,因为它们可能会被恶意用户获取。 总之,PHP Session 是一个强大的工具,用于跟踪用户状态,创建更...
首先,我们要了解的是PHP小偷程序的实现原理,它通常包括以下几个步骤:获取目标网站的HTML页面、解析HTML页面以获取所需数据的连接地址、使用二进制读取方式获取内容并保存到本地服务器、最后对保存的文件进行...
`读取并发送文件内容。 总的来说,`header()`函数在PHP开发中扮演着多面手的角色,通过灵活地设置HTTP头信息,可以实现多种功能,优化用户体验并增强服务器与客户端的交互。但使用时一定要注意避免在发送头信息前...
然后,使用 `while` 循环读取目标主机的响应,并检查响应状态码是否为 200 OK。 获取真实的文件地址 如果响应状态码为 200 OK,则使用 `header` 函数将浏览器重定向到真实的文件地址。否则,继续执行程序,使用 `...
while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } // 读取完成的请求信息 while ...