在平常业务开发过程当中,咱们可能有遇到一些文件相关操做,好比读取大文件啦,好比读取文件最后几行啦,这些操做在 shell 中都比较容易实现,那么在 PHP 中咱们如何实现呢,下面就让咱们来看一下。php
直接使用 file 函数将整个文件读入一个数组内,还能够经过 file_get_contents 函数以字符串形式获取文件的内容。html
咱们来看一下 PHP 官方给的 file 函数的示例:git
<?php
// 将一个文件读入数组。本例中经过 HTTP 从 URL 中取得 HTML 源文件。
$lines = file('http://www.example.com/');
// 在数组中循环,显示 HTML 的源文件并加上行号。
foreach ($lines as $line_num => $line) {
echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}
// 另外一个例子将 web 页面读入字符串。参见 file_get_contents()。
$html = implode('', file('http://www.example.com/'));
// 从 PHP 5 开始能够使用可选标记参数
$trimmed = file('somefile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
?>
复制代码
咱们来看一下这样作有什么问题。file
函数会一次性将文件内容读取到内存中,而 PHP 为了防止一些脚本占用了太多的内存而对每一个线程的最大可用内存进行了限制,该限制在 php.ini
中配置,参数为 memory_limit
。github
memory_limit
参数做用是设置了一个脚本容许分配的最大内存量,以字节(bytes)为单位。这有助于防止写得很差的脚本吃掉服务器上全部可用的内存。若是不须要内存限制,请将此指令设置为 -1
。默认值为 128M
。web
平常业务开发中,建议不要将该值设置为 -1
,不然一旦有哪一个进程耗尽了内存,影响了正常业务,那后果就很是严重了。shell
考虑到一次性读取整个文件会耗费大量的内存,并且假设程序有部分功能是从文件中读取数据,而后去数据库中查找数据,数据库也不可能一次性查找全部数据,所以咱们能够分批查询,对应到文件中能够是一行一行读取。数据库
下面一个方法是计算分配给程序内存的峰值的函数;数组
<?php
memory_get_peak_usage();
function formatBytes($bytes, $precision = 2) {
$units = array("b", "kb", "mb", "gb", "tb");
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= (1 << (10 * $pow));
return round($bytes, $precision) . " " . $units[$pow];
}
print formatBytes(memory_get_peak_usage());
?>
复制代码
下面一个函数咱们来逐行读取文件,注意最后须要执行 fclose
函数服务器
<?php
function readTheFile($fileName) {
$line = [];
$handle = fopen($fileName, "r");
while (!feof($handle)) {
$line[] = ltrim(fgets($handle));
}
fclose($handle);
return $line;
}
readTheFile("name.txt");
require "memory.php";
?>
复制代码
函数功能:markdown
一个生成器函数看起来像一个普通的函数,不一样的是普通函数返回一个值,而一个生成器能够 yield 生成许多它所须要的值。
当一个生成器被调用的时候,它返回一个能够被遍历的对象。当你遍历这个对象的时候(例如经过一个 foreach 循环),PHP 将会在每次须要值的时候调用生成器函数,并在产生一个值以后保存生成器的状态,这样它就能够在须要产生下一个值的时候恢复调用状态。
一旦再也不须要产生更多的值,生成器函数能够简单退出,而调用生成器的代码还能够继续执行,就像一个数组已经被遍历完了。
生成器函数的核心是 yield 关键字。它最简单的调用形式看起来像一个 return 申明,不一样之处在于普通 return 会返回值并终止函数的执行,而 yield 会返回一个值给循环调用今生成器的代码而且只是暂停执行生成器函数。
<?php
function yieldCommand($fileName) {
$line = [];
$handle = fopen($fileName, "r");
while (!feof($handle)) {
yield ltrim(fgets($handle));
}
fclose($handle);
}
foreach (yieldCommand("name.txt") as $key => $value) {
echo $value;
}
require "memory.php";
?>
复制代码
能够优化 php 的性能
节省大量的内存
适合大量数据计算
当咱们想获取文件中最后几行数据的时候,咱们知道在 shell 中直接使用 tail
命令很是容易得到,那么咱们能不能在 PHP 中执行 shell 命令呢?答案是能够的。
在 PHP 中,咱们有三个函数能够执行 shell 命令,这三个函数分别为 system、exec、passthru。这三个函数的区别以下:
咱们来测试一下:
<?php
function tailCommand($fileName) {
$cmd = "tail -n 10 $fileName";
$result = system($cmd);
return $result;
}
tailCommand("name.txt");
require "memory.php";
?>
复制代码
escapeshellarg
函数的功能是把字符串转码为能够在 shell 命令里使用的参数。