もしある文字列がIPアドレスか調べたい場合、PHPでは次の2つの方法が使えます。
- 正規表現で範囲チェック
- filter_var関数を使ったチェック
一般的には正規表現を使うのが多いですが、filter_var関数でも同じことが可能です。
そういう訳でこの2つのチェック方法とそのコード例を紹介
このページの目次
IPアドレスの範囲について
まず初めにIPアドレスの範囲について少しだけ解説
そもそもIPアドレスには次の2つの形式があります。
- IPv4
- IPv6
そしてこの2つの範囲は次で説明する通り
まずIPv4の方ですが、これは次のような形式を持つIPです。
1 |
xxx.xxx.xxx.xxx |
ドット ( . ) で区切られた xxx には 0 ~ 255 までの数値(10進数)が入ります。
つまりIPv4の範囲は 0.0.0.0 ~ 255.255.255.255 までの間ということ
そして次にIPv6ですが、これは次のような形式を持つIPアドレスです。
1 |
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx |
セミコロン ( : ) で区切られた xxxx には 0 ~ fff までの数値(16進数)が入ります。
つまりIPv6形式のアドレスの範囲は 0:0:0:0:0:0:0:0 ~ ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff までの間ということ
ただし16進数で表現されることに注意が必要です。
以上がIPアドレスの2つの形式 IPv4 と IPv6 の範囲
ここではこのどちらか一方ではなく、どちらでも範囲チェックできる方法を紹介します。
IPアドレスチェックの2つの方法
IPの範囲チェック方法は冒頭でも触れたように次の2つ
- 正規表現で範囲チェック
- filter_var関数を使ったチェック
個人的には長い正規表現を書くよりもfilter_var関数を使う方がスマートだと思います。
この2つの方法の具体的なやり方とかコード例は次の通り
正規表現でIPの範囲チェック
IPの範囲チェックというと真っ先に思いつくのがこの正規表現
IPv4またはIPv6にマッチする正規表現を書いて preg_match で判定するだけです。
まずIPv4にマッチさせたい場合、次のような正規表現を書けばOK
1 |
(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) |
このQiitaページから引用したものですが、やっぱり長いですね・・・
そして次がIPv6とマッチさせる正規表現
1 |
((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$ |
これはこちらのページに書かれていたものですが、めちゃくちゃ長いです。笑
IPv6には細かなルールがあって厳密にマッチさせたい場合はここまで長くなる模様
それでこれらの正規表現をpreg_match関数で使えばIPが正しいかチェックできます。
例えば次はIpv4の範囲チェックを行っているコード例
1 2 3 4 5 6 7 8 9 10 11 |
/** チェックしたいIPアドレス */ $ipv4 = '127.0.0.1'; /** IPv4形式とマッチする正規表現 */ $pattern = '/(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/'; if( preg_match( $pattern, $ipv4 ) ){ echo "'$ipv4'は有効な範囲内にあるIPアドレス"; }else{ echo "'$ipv4'は不正または無効な範囲内にあるIPアドレス"; } |
IPv6の場合も正規表現を変えれば同様に範囲チェックが可能です。
以上が正規表現を使ったIPアドレスのチェック方法
IPv4はまだしもIPv6は厳密にマッチさせようとすると長ったらしくなります。
filter_var関数でIPの範囲チェック
お次はPHPでデータをフィルタリングする関数 filter_var を使う方法
次のようにチェックデータを $data 、フィルタする形式を $filter として実行します。
1 |
$filtered_data = filter_var( $data, $filter ); |
そして返り値は
- フィルタ形式に当てはまる場合はフィルタリングされたデータ、
- もし不正な形式のデータだった場合は FALSE
が返ってくるようです。
IPアドレスのチェックにはフィルタ形式に FILTER_VALIDATE_IP を渡せばOK
もし filter_var の返り値が FALSE なら正しいIPアドレスじゃないと分かる訳です。
例えば次はIPv4形式のIPの範囲チェックをしているコード例
1 2 3 4 5 6 7 8 |
/** チェックしたいIPアドレス */ $ipv4 = '127.0.0.1'; if( filter_var( $ipv4, FILTER_VALIDATE_IP ) ){ echo "'$ipv4'は有効な範囲内にあるIPアドレス"; }else{ echo "'$ipv4'は不正または無効な範囲内にあるIPアドレス"; } |
さっきの正規表現を使う方法よりも大分スマートです。
もちろんIPv4だけでなくIPv6での範囲チェックも可能
1 2 3 4 5 6 7 8 |
/** チェックしたいIPv6形式のアドレス */ $ipv6 = '2001:0db8:1234:5678:90ab:cdef:0000:0000'; if( filter_var( $ipv6, FILTER_VALIDATE_IP ) ){ echo "'$ipv6'は有効な範囲内にあるIPアドレス"; }else{ echo "'$ipv6'は不正または無効な範囲内にあるIPアドレス"; } |
あの長ったらしい正規表現を使わなくていいので楽ですね。
以上がfilter_var関数でIPアドレスの範囲チェックを行う方法
こちらの方が正規表現を使うよりコードも少なく、簡単にチェックができます。
補足 : メルアドやURLを形式チェックするには・・
ここまででIPアドレスの形式チェック方法を紹介してきました。
filter_var関数を使った方が正規表現を長々と書くよりも簡単ですね。
ちなみにfilter_var関数ではメルアドやURLの形式チェックも可能です。
詳しいやり方やコード例は次記事をどうぞ
IPアドレスと同じく規格的に正しい形式かどうかを数行のコードで簡単に判定できます。
ここまでのまとめ
ということでIPアドレスの範囲チェック方法をもう一度まとめ
- 正規表現で範囲チェック
IPアドレスのパターンにマッチするかを preg_match を使って判定する。
ただしパターンがとてつもなく長くなるのでベストな方法ではない - filter_var関数で範囲チェック
この関数のフィルタ形式に FILTER_VALIDATE_IP を渡せば判定できる
こっちの方が長ったらしい正規表現が必要ない分だけスマート
PHPではfilter_var関数を使った方が楽に範囲チェックができそうですね。
正規表現も悪くはないですが、あそこまで長くなるとちょっと・・・という感じです。
以上PHPでIPアドレスの範囲チェックを行う方法についてでした。