1

私はPHPについてほとんど知らないので、RedHatキックスタートファイルを生成するためのWebベースのツールの作成は学ぶのに良いプロジェクトになると判断しました。特に、ツールはCSVファイルを解析し、そこから取得したデータを含むテーブルを生成します。入力ファイルの形式は次のとおりです。

host1,10.153.196.248,255.255.255.0,10.153.196.1,00:50:56:ac:69:cb
、10.153.157.113,255.255.255.128,10.153.157.1
、10.153.157.241,255.255.255.128,10.153.157.129、
、/ home、10 、、、
、スワップ、10 、、、
、/ opt、60 、、、
、/ data、30 、、、
、、、、、、
host2,10.153.155.124,255.255.255.128,10.153.155.1,00:50:56:ac:69:ce
、10.153.157.114,255.255.255.128,10.153.157.1
、10.153.157.242,255.255.255.128,10.153.157.129、
、/ home、10 、、、
、スワップ、10 、、、
、/ opt、60 、、、
、/ data、30 、、、
、、、、、、

テキストの各セクションは、1台のサーバーの情報を表します。フィールドは次のとおりです。

ホスト名、eth0 IP、eth0ネットマスク、eth0ゲートウェイ、eth4 MAC
null、eth1 IP、eth1ネットマスク、eth1ゲートウェイ、null
空白、eth2 IP、eth2ネットマスク、eth2ゲートウェイ、null
null、パーティション名、GB単位のパーティションサイズ、null、null
null、パーティション名、GB単位のパーティションサイズ、null、null
null、パーティション名、GB単位のパーティションサイズ、null、null
null、パーティション名、GB単位のパーティションサイズ、null、null
null、null、null、null、null

現時点では、それを解析して、入力ファイルの各行がテーブルの行であるテーブルを生成できます。これを処理する関数:

function processFile($workFile) {

    if (file_exists($workFile)) {
        print '<table>';
        $fh = fopen("$workFile", 'rb');
        if ($fh) {
            for ($line = fgets($fh); !feof($fh); $line = fgets($fh)) {
                $line = trim($line);
                $info = explode(',', $line);
                print '<tr><td>' . $info[0] . '</td><td>' . $info[1] . '</td><td>' . $info[2] . '</td><td>' . $info[3] . '</td></tr>';
            }
        } else {
            print "Failed to open $workFile";
        }
        print '</table>';
    } else {
        print "File $workFile does not exist";
    }

}

生成するもの:

host1 eth0IPeth0ネットマスクeth0ゲートウェイ
          eth1IPeth1ネットマスクeth1ゲートウェイ
          eth2IPeth2ネットマスクeth2ゲートウェイ
          パーティション1パーティション1サイズ
          パーティション2パーティション2サイズ
          パーティション3パーティション3サイズ
          パーティション4パーティション4サイズ
host2 eth0IPeth0ネットマスクeth0ゲートウェイ
          eth1IPeth1ネットマスクeth1ゲートウェイ
          eth2IPeth2ネットマスクeth2ゲートウェイ
          パーティション1パーティション1サイズ
          パーティション2パーティション2サイズ
          パーティション3パーティション3サイズ
          パーティション4パーティション4サイズ

これが始まりです。ただし、すべてのサーバーに4つのパーティションがあるわけではありません。いくつかはもっと多く、いくつかは1つか2つ少なくなります。そして、事前にその情報を知らないと、各サーバーのパーティション情報の下に行を追加し、各サーバーを独自のテーブルに分割するという、私がやりたいことの妨げになります。これに沿った何か:

host1 eth0IPeth0ネットマスクeth0ゲートウェイ
          eth1IPeth1ネットマスクeth1ゲートウェイ
          eth2IPeth2ネットマスクeth2ゲートウェイ
          パーティション1パーティション1サイズ
          パーティション2パーティション2サイズ
          パーティション3パーティション3サイズ
          パーティション4パーティション4サイズ
          パーティション5パーティション5サイズ
          パーティション6パーティション6サイズ
          ディスクはいくつですか?[テキストフィールド}    

host2 eth0IPeth0ネットマスクeth0ゲートウェイ
          eth1IPeth1ネットマスクeth1ゲートウェイ
          eth2IPeth2ネットマスクeth2ゲートウェイ
          パーティション1パーティション1サイズ
          パーティション2パーティション2サイズ
          パーティション3パーティション3サイズ
          パーティション4パーティション4サイズ
          ディスクはいくつですか?[テキストフィールド}

私の一般的な考えは、CSVファイルのフィールドに、行にパーティション情報が含まれていることを示す必要があるということです。それは最も簡単なアプローチのようです。ただし、入力ファイルの形式を変更する必要がない別の手段があるかどうか疑問に思っています。

また、すべてのnullフィールドを含む行をセクション区切り文字として使用する方法も理解する必要があります。

私がこれにどのようにアプローチできるかについての考えはありがたいです。

4

2 に答える 2

0
echo('<table>');
$i = 0;
while($data = fgetcsv($fh)) {
    echo('<tr>');
    $cellTag = 'td';
    if($i == 0) {
        $cellTag = 'th';
    }
    $i++;
    foreach($data as $cell) {
        echo('<'.$cellTag.'>'.$cell.'</'.$cellTag.'>');
    }
    echo('</tr>');
}
echo('</table>');

試してみてください。初めて機能しない場合は、Lemmeを知っておいてください。私はそれをテストしただろうが、CSVファイルを手元に持っていない.

于 2012-10-30T22:26:24.237 に答える
0

特定の形式に一致する必要があるデータを解析しているため、それは本質的に規則的である必要があり、正規表現を使用して必要な入力に厳密に一致させることができます (そうでないものは破棄します)。

$rows = explode("\n", $input);

// @link http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address
$regIp = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])";
$regHost = "(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])";

$hosts = array();
foreach ($rows as $row) {
  $matches = null;
  if (preg_match("/(?<host>$regHost),(?<ip>$regIp),(?<netmask>$regIp),(?<gateway>$regIp),(?<mac>.*)/", $row, $matches)) {
    $host = $matches['host'];
    $hosts[$host]['name'] = $matches['host'];
    $hosts[$host]['mac'] = $matches['mac'];
    $hosts[$host]['eth'][] = array(
      'ip'      => $matches['ip'],
      'netmask' => $matches['netmask'],
      'gateway' => $matches['gateway'],
    );
  } else if (preg_match("/,(?<ip>$regIp),(?<netmask>$regIp),(?<gateway>$regIp),/", $row, $matches)) {
    $hosts[$host]['eth'][] = array(
      'ip'      => $matches['ip'],
      'netmask' => $matches['netmask'],
      'gateway' => $matches['gateway'],
    );
  } else if (preg_match("/,(?<name>.+),(?<size>\d+),,,/", $row, $matches)) {
    $hosts[$host]['partition'][] = array(
      'name' => $matches['name'],
      'size' => $matches['size'],
    );
  } else if (preg_match("/,,,,,/", $row)) {
    // we already partition output array with value of `$host` variable.
    echo "Found terminating row\n"; 
  } else {
    echo "Unrecognised data on row: $row\n";
  }
}

var_export($hosts);

CSV ファイルを扱っているため$fields = str_getcsv($row)、ループ内で使用して各フィールドを含む配列を取得することもできます。次に、配列に含まれるフィールドの数、空のフィールドの数を数え、各フィールドに何が含まれているかを検証する必要があります。

各 CSV 行の文字列表現で正規表現を直接使用すると、上記のすべてを 1 つの式で厳密に一致させることができます。各正規表現の(?<var>...)部分は名前付き一致です。OP によって提供される入力を使用して、上記のスクリプトは次のように出力します。

Found terminating row
Found terminating row
array (
  'host1' => 
  array (
    'name' => 'host1',
    'mac' => '00:50:56:ac:69:cb',
    'eth' => 
    array (
      0 => 
      array (
        'ip' => '10.153.196.248',
        'netmask' => '255.255.255.0',
        'gateway' => '10.153.196.1',
      ),
      1 => 
      array (
        'ip' => '10.153.157.113',
        'netmask' => '255.255.255.128',
        'gateway' => '10.153.157.1',
      ),
      2 => 
      array (
        'ip' => '10.153.157.241',
        'netmask' => '255.255.255.128',
        'gateway' => '10.153.157.129',
      ),
    ),
    'partition' => 
    array (
      0 => 
      array (
        'name' => '/home',
        'size' => '10',
      ),
      1 => 
      array (
        'name' => 'swap',
        'size' => '10',
      ),
      2 => 
      array (
        'name' => '/opt',
        'size' => '60',
      ),
      3 => 
      array (
        'name' => '/data',
        'size' => '30',
      ),
    ),
  ),
  'host2' => 
  array (
    'name' => 'host2',
    'mac' => '00:50:56:ac:69:ce',
    'eth' => 
    array (
      0 => 
      array (
        'ip' => '10.153.155.124',
        'netmask' => '255.255.255.128',
        'gateway' => '10.153.155.1',
      ),
      1 => 
      array (
        'ip' => '10.153.157.114',
        'netmask' => '255.255.255.128',
        'gateway' => '10.153.157.1',
      ),
      2 => 
      array (
        'ip' => '10.153.157.242',
        'netmask' => '255.255.255.128',
        'gateway' => '10.153.157.129',
      ),
    ),
    'partition' => 
    array (
      0 => 
      array (
        'name' => '/home',
        'size' => '10',
      ),
      1 => 
      array (
        'name' => 'swap',
        'size' => '10',
      ),
      2 => 
      array (
        'name' => '/opt',
        'size' => '60',
      ),
      3 => 
      array (
        'name' => '/data',
        'size' => '30',
      ),
    ),
  ),
)

適切に構造化されたデータの配列ができたので、データを必要な形式 (つまり、HTML テーブル) で出力するのは簡単です。

于 2012-10-30T23:33:33.527 に答える