以下是我试图查看我们的PBX上的日志的代码。它运行正常,对日志文件进行排序,显示所有数据等。问题是,一旦完成,它会在内存中保留大量数据(几百MB)。我需要在完成后将其清除,但无法弄清楚如何完成。如果它运行了几次,它会从服务器中吸取所有RAM,我们就会开始出错。提前谢谢!
<!DOCTYPE html>
<html>
<title>Call Search</title>
<body>
<?php
function getBetween($var1, $var2, $pool)
{
$temp1 = strpos($pool, $var1) + strlen($var1);
$result = substr($pool, $temp1, strlen($pool));
$dd=strpos($result, $var2);
if($dd == 0){$dd = strlen($result);}
return substr($result, 0, $dd);
}
if(!isset($_POST['phonenum']) && !isset($_POST['WantedCallID']))
{
echo '<form action="test.php" method="post">';
echo '<h4>Please enter the number you wish to search for...</h4><input type="text" name="phonenum">';
echo '<input type="submit" value="Go">';
echo '</form>';
}
else if(isset($_POST['WantedCallID']))
{
$counter = 0;
$logfile="calllog";
while (file_exists("/var/log/".$logfile))
{
if($counter==0){$logfile="calllog";}
else{$logfile="callog.".$counter;}
$path = "/var/log/".$logfile;
$logtoarray = file($path);
foreach ($logtoarray as $linenumber => $line)
{
if(strpos($line, "[".$_POST['WantedCallID']."]") !== false){echo $line." <br>";}
}
$counter++;
}
}
else
{
$counter = 0;
$logfile="calllog";
$arrayCounter = 0;
while (file_exists("/var/log/".$logfile))
{
if($counter == 0){$logfile = "calllog";}
else{$logfile="calllog.".$counter;}
$path = "/var/log/".$logfile;
if(file_exists($path))
{
$logtoarray = file($path);
$oldCallId = "";
$currentCallId = "";
foreach ($logtoarray as $linenumber => $line)
{
if(strpos($line, $_POST['phonenum']) !== false && strpos($line, "VERBOSE[") !== false)
{
$currentCallId = getBetween("VERBOSE[", "]", $line);
if($currentCallId !== $oldCallId)
{
$callIdArray[$arrayCounter] = "Date: ".substr($line, 0, 22)." Call ID:".$currentCallId."\n";
echo "Date: ".substr($line, 0, 22)." Call ID:".$currentCallId."<br>";
$oldCallId = $currentCallId;
}
}
$arrayCounter++;
}
}
else{break;}
$counter++;
}
echo '<form action="test.php" method="post">';
echo '<h4>Please enter the call ID you wish to search for...</h4><input type="text" name="WantedCallID">';
echo '<input type="submit" value="Go">';
echo '</form>';
}
$variables = array_keys(get_defined_vars());
foreach($variables as $variable) {
unset(${"$variable"});
}
unset($callIdArray);
?>
</body>
</html>
答案 0 :(得分:2)
我将假设您通过Apache服务器运行此脚本。这是一个相当普遍的问题,尽管我经常通过调整图像来看到它。
一旦Apache的孩子(运行PHP的进程)有了大量的内存,或者更常见的是PHP,由于使用了大量数据而增加了,它没有一种方法可以返回内存到操作系统。
相反,每个子进程都有MaxRequestsPerChild
设置。这可能设置为0
- 永不重启。如果膨胀内存大小是一个问题,那么将其设置为几百或几千可能是有用的。在那么多请求之后,apache子节点重新启动,所以捕获的所有内存都返回到操作系统,如果需要,新的子节点会被启动。虽然在重新启动进程时请求可能需要更长的时间,但释放内存会更有用。
答案 1 :(得分:0)
以下是对代码的简单修改,它将一次读取一行日志文件,而不是将整个文件读入内存。
while (file_exists("/var/log/".$logfile))
{
if($counter == 0){$logfile = "calllog";}
else{$logfile="calllog.".$counter;}
$path = "/var/log/".$logfile;
if(file_exists($path))
{
$fh = fopen($path, 'r'); //change
$linenumber = 0; //addition
$oldCallId = "";
$currentCallId = "";
while( $line = fgets($fh) ) //change
{
$linenumber++; //addition
if(strpos($line, $_POST['phonenum']) !== false && strpos($line, "VERBOSE[") !== false)
{
$currentCallId = getBetween("VERBOSE[", "]", $line);
if($currentCallId !== $oldCallId)
{
$callIdArray[$arrayCounter] = "Date: ".substr($line, 0, 22)." Call ID:".$currentCallId."\n";
echo "Date: ".substr($line, 0, 22)." Call ID:".$currentCallId."<br>";
$oldCallId = $currentCallId;
}
}
$arrayCounter++;
}
fclose($fh); //addition
}
}