将IPTables输出拆分为数据库的多维数组


Splitting IPTables output to a multidimensional array for database

我正试图将Debian服务器中的当前IPTables规则整齐地列在数据库中。

为此,我写了几个步骤。

  1. 首先,我们得到带有行号的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() 中的此尝试