IP アドレスから携帯キャリアを判別する。
127.0.0.1 のようなドット表記の IP アドレスから、携帯キャリアを判別する関数を生成します。
検索部分は http://d.hatena.ne.jp/tasukuchan/20071231/1199105717 を参考にしました。
異なる部分として
- 全部 PHP 。
- IP アドレスは手動設定。
- フルブラウザの IP アドレスなどは除外したかった。
- クローラ作るのも面倒だし、いっそ手動ということで。
- コードサイズの圧縮。相当小さくなります。
- else がありません。 if と elseif だけ。
- 32bit と 64bit を分けた。
- 必ず int で比較するようにする為。
- 当然、32/64bit 間で互換性はなし。それぞれ別個に生成すること。
- →やっぱり止めた。
重要部分の抜粋。
<?php $imode = array( '124.146.174.0/24', '124.146.175.0/24', '210.136.161.0/24', '210.153.84.0/24', '210.153.86.0/24'); $ezweb = array( /* 省略 */ ); $yahoo = array( /* 省略 */ ); $crawlers = array( /* 省略 */ ); // キーがそのまま返り値になる。 $map = array( 1 => $imode, 2 => $ezweb, 3 => $yahoo, 4 => $crawlers); // 返り値に文字列を使いたい場合、 // $map = array("'imode'" => $imode); // のようにする。
生成物。
<?php function mobile_ip2carrier($v){$n=ip2long($v);if(!defined('PHP_INT_SIZE')||PHP_INT_SIZE!==8)$n=(float)sprintf('%u',$n);if($n<2085863194){if($n<1989727936){if($n<1123631104){if($n<1009460477){if($n>=998712960&&$n<=998713087)return 2;}elseif($n<=1009460477)return 4;elseif($n>=1031078144&&($n<=1031078159||$n>=1031078432&&$n<=1031078447))return 2;}elseif($n<=1123635199)return 4;elseif($n<1867943552){if($n<1208928000){}elseif($n<=1208928127)return 4;elseif($n>=1867943232&&$n<=1867943487)return 2;}elseif($n<=1867943743||$n>=1867943872&&($n<=1867943935||$n>=1867944704&&$n<=1867944959))return 2;}elseif($n<=1989727999)return 2;elseif($n<2037375904){if($n<1990165760){if($n>=1990165248&&($n<=1990165375||$n>=1990165664&&$n<=1990165695))return 2;}elseif($n<=1990165887||$n>=1990165952&&($n<=1990166015||$n>=2037375744&&$n<=2037375871))return 2;}elseif($n<=2037375935)return 2;elseif($n<2085855122){if($n<2037376768){}elseif($n<=2037376895)return 2;elseif($n>=2070736128&&$n<=2070736159)return 3;}elseif($n<=2085855161||$n>=2085855200&&($n<=2085855223||$n>=2085863176&&$n<=2085863177))return 4;}elseif($n<=2085863197)return 4;elseif($n<3533263872){if($n<3412655616){if($n<3404050432){if($n<2089987584){}elseif($n<=2089988095)return 1;elseif($n>=3403013473&&$n<=3403013473)return 4;}elseif($n<=3404051199)return 1;elseif($n<3404621694){}elseif($n<=3404621694)return 4;elseif($n>=3405603040&&$n<=3405603071)return 3;}elseif($n<=3412655871)return 4;elseif($n<3512069632){if($n>=3414423552&&($n<=3414425599||$n>=3419996016&&$n<=3419996021))return 4;}elseif($n<=3512069759)return 4;elseif($n<3532169472){}elseif($n<=3532169727)return 1;elseif($n>=3532785600&&$n<=3532785663)return 3;}elseif($n<=3533264127)return 1;elseif($n<3681328640){if($n<3538321632){if($n<3533264384){}elseif($n<=3533264639)return 1;elseif($n>=3534684544&&$n<=3534684671)return 3;}elseif($n<=3538321647)return 2;elseif($n<3671425024){}elseif($n<=3671429119)return 4;elseif($n>=3681328384&&$n<=3681328511)return 2;}elseif($n<=3681328671)return 2;elseif($n<3682439680){if($n>=3681328680&&($n<=3681328687||$n>=3682439424&&$n<=3682439551))return 2;}elseif($n<=3682439695||$n>=3682440192&&($n<=3682440319||$n>=3724885632&&$n<=3724886015))return 2;return 0;}
利用例。
<?php $ip = '124.146.174.1'; // i モード $carrier = ''; switch (mobile_ip2carrier($ip)) { case 1: $carrier = 'imode'; break; case 2: $carrier = 'ezweb'; break; case 3: $carrier = 'yahoo'; break; case 4: $carrier = 'crawler'; break; default /* case false */: $carrier = 'unknown'; break; } echo "$ip: $carrier"; // 124.146.174.1: imode
ソース。
Q. 本当に PHP でやる必要はあるのか?
A. うーん……。
Q. 他に最適化するところあるよね?
A. ううーん……。
まあ、一度作ってしまえば結構便利ですよと。