4

この質問が何度も出されていることは知っていますが、最終的な解決策はどこにも見つかりませんでした。だからここに行きます:

DB を知らなくても、ベストプラクティスを使用して IP (IPv4 と IPv6 の両方) を DB 内に保存するにはどうすればよいですか? これは、PHP PDO などの DB 抽象化の目的の場合です。

マイナーな注意として、Windows で PEAR が必要だったので、PHP 5.2.17 を使用しています。

これを varbinary(16) として保存し、mysql 関数 inet6_ntop および inet6_pton を使用して IP を文字列としてやり取りすることを提案する人がいます。IPv6機能でMySQL 5を拡張することが示唆されています。PHP では、この質問のThiefMasterが示唆しているように、関数 inet_pton() および inet_ntop() は IPv4 と IPv6 をバイナリ形式に変換できますが、バイナリ コンテンツを SQL INSERT/UPDATE 文字列に渡す方法は不明です (およびこれらの php 関数は、Windows の php 5.3.0 でのみ提供されますが、これらをリバース エンジニアリングすることは可能です)。Jakeが行ったことと、DB 内の IP の整数表現に関する彼の結果が本当に気に入っています。、これを DB に実装する場合、これは遠く離れた不測の将来に役立つかもしれませんが、PHP PDO を使用した DB 抽象化の DB 相互互換性については確信が持てません。この投稿は、バイナリ値の保存に関する適切な回答を提供しているようですが、文字列へのエスケープされていないバイナリ インジェクションは潜在的な危険ではありませんか? また、このルートをたどると、何人の DB が varbinary(16)/int(128bit) を表現 IP に変換できますか? 開発者がクイック ルックアップを実行したい場合は?

最も簡単な方法は、ip文字列をそのままvarchar(45)に挿入することです。しかし、PHP ( djmaze(AT)dragonflycms(.)orgとして、またはFF dot st の MagicalTuxとしてリバース エンジニアリングされている) で inet_ntop() および inet_pton() 関数を使用して、複雑なルートをたどりたい人は、どのように保存しますか? IPv6をバイナリとして取得しますか? <?php $strIP = "2001:4860:b002::68"; ?>から PDO を使用し、INSERT を使用してから SELECT 準備済みステートメントを使用する例を誰かが挙げることができますか?

ご覧のとおり、私は調査を行いましたが、この IPv6 の最終的な優れた実践方法は明確ではありません。

4

1 に答える 1

2

あなたの研究が示しているように、IP アドレスを標準形式の文字列、バイナリ文字列、または整数として保存することには、利点と問題があります。おそらく、IP アドレスをデータベースに保存するための妥協点があるでしょう。

それらを文字列として保存するのはどうですか。ただし、最大長まで拡張してください。そうすれば、それら (==、>、< など) を比較することはできますが、それでも読み取り可能であり、特殊文字の特別な入力および出力エンコーディングは必要ありません。

これを行う方法の例:

function expand_ip_address($addr_str) {
  /* First convert to binary, which also does syntax checking */
  $addr_bin = @inet_pton($addr_str);
  if ($addr_bin === FALSE) {
    return FALSE;
  }

  /* Then differentiate between IPv4 and IPv6 */
  if (strlen($addr_bin) == 4) {
    /* IPv4: print each byte as 3 digits and add dots between them */
    return implode('.', array_map(
      create_function('$byte', 'return sprintf("%03d", ord($byte));'),
      str_split($addr_bin)
    ));
  } else {
    /* IPv6: print as hex and add colons between each group of 4 hex digits */
    return implode(':', str_split(bin2hex($addr_bin), 4));
  }
}

そしていくつかの例:

/* Test IPv4 */
var_dump(expand_ip_address('192.0.2.55'));

/* Test IPv6 */
var_dump(expand_ip_address('2001:db8::abc'));

/* Test invalid */
var_dump(expand_ip_address('192:0:2:55'));

生成するもの:

string(15) "192.000.002.055"
string(39) "2001:0db8:0000:0000:0000:0000:0000:0abc"
bool(false)
于 2013-01-21T11:49:34.707 に答える