我正试图将Debian服务器中的当前IPTables规则整齐地列在数据库中。
为此,我写了几个步骤。
-
首先,我们得到带有行号的IPTables输出。(例如输入链)
iptables-L INPUT-nvx—行
我得到了一个整洁的输出,我想以完全相同的方式在数据库中得到它。例如
Number, Chain, Protocol, Port, in, out
等等。
为了使这个输出与导入数据库兼容,我需要将它放入一个多维数组中。这就是我被卡住的地方。它需要这样;
[0] (entry of rule)
[number],[chain],[protocol]...
[1]
[number],[chain],[protocol]
我怎样才能以最有效的方式做到这一点?
--更新代码--
function getIPTables() {
$processHandle = popen('/usr/bin/sudo /sbin/iptables -L INPUT -nvx --line-numbers | tail -n +3', 'r');
$content = '';
while (!feof($processHandle)) {
$content .= fread($processHandle, 4096);
}
pclose($processHandle);
// break out all new lines into an array
$lines = explode("'n", $content);
foreach ($lines as $line) {
$commands = array();
$segments = explode(" ", $line);
$newEntry = array(
'Number' => $segments[0],
'Chain' => $segments[1],
'Protocol' => $segments[2],
'Port' => $segments[3],
'in' => $segments[4],
'out' => $segments[5]
);
array_push($commands, $newEntry);
print_r($commands);
}
}
--输出--
root@debian:/home/michael/Documents/PHPCLIFILES# php getAllRules
Local DB rules from users loaded in array
PHP Notice: Undefined offset: 1 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 47
PHP Notice: Undefined offset: 2 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 48
PHP Notice: Undefined offset: 3 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 49
PHP Notice: Undefined offset: 4 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 50
PHP Notice: Undefined offset: 5 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 51
我假设您的正则表达式是正确的。实际上,您正在使用$commands .= <some text>
将所有内容附加到同一个字符串中。与其将其附加到同一个字符串,不如将$commands
设置为一个数组。然后,您需要为进入的每一行实例化一个新数组($line
)。push
——你想保留在$line
阵列上的东西,在每一行的末尾你都要array_push($commands, $line)
Array_push()
:http://php.net/manual/en/function.array-push.php
这可能是您的foreach()
的一种方法
foreach ($lines as $line) {
$commands = new array;
if (empty($line)) {
continue; //empty lines are silly
}
// ... do all the checks to validate if you currently have a valid LINE
//We know that whatever we have now is a valid line
$segments = explode(line bla bla); //explode this line on tabs or spaces .. dunno what the output of your console is.
//At this point you know exactly where every part you need is, considering the console always gives the same output.
//Either you do some validations here, or you go for the lazy approach and go:
$newEntry = array(
'Number' => $segments[0],
'Chain' => $segments[1],
'Protocol' => $segments[2],
'Port' => $segments[3],
'in' => $segments[4],
'out' => $segments[5]
);
array_push($commands, $newentry);
}
代码没有经过测试,但你应该知道我要去哪里。
您的代码:
//instantiate a new empty named variable.
$commands = '';
//for every line in your console-dump file
foreach ($lines as $line) {
//Is the line empty
if (empty($line)) {
//skip line and go to next line
continue;
}
//Does the line start with #
if (preg_match('/^#/', $line) === 1) {
//skip line and go to next line
continue;
}
//Does the line start with *
if (preg_match('/^'*/', $line) === 1) {
//skip line and go to next line
continue;
}
//Does the line start with 'COMMIT'
if (preg_match('/^COMMIT/', $line) === 1) {
//skip line and go to next line
continue;
}
//we have a valid line now, so let's do stuff
$match = array();
//Does the line contain:
if (preg_match('/^:([A-Z ]*).*/', $line, $match) === 1) {
//skip line and go to next line
continue;
}
//Only if the line is a 'valid' line, and does not have your last match,
//Then you will append "iptables {$line}'n" to $commands
$commands .= "iptables {$line}'n";
//This way it was a bit useless for you to cut up the line using the preg_match
//and store it into $match, cause you don't do anything with $match
}
你最初的方法很好。并且取决于您的控制台如何返回可预测值,您要么使用regex遵循您的方法(但随后实际使用结果),要么使用我建议的惰性方法。
请注意,CONTINUE
实际上打破了当前循环,并进入下一次迭代。
$array = array(1, 2, 3, 4, 5);
foreach($array as $number){
if($number < 3){
continue;
}
print($number .''n');
}
结果将是:
3'n
4'n
5'n
因为continue实际上完全停止了foreach()
中的此尝试