MobilePhoneAddress クラス

何これ?

現在アクセスしているクライアント、または指定した IP アドレス (IPv4 アドレス) がどのキャリアのものか判定する関数をまとめたクラスです。

何に使うの?

携帯電話機器の判定が出来ると色々出来るんじゃないでしょうか。 少なくとも、私が開発した某サイトではこれと似たクラスを用いて色々制御しています。 例えば、GIF/PNG の表示を切り替えたりとか、そもそもクライアントを限定したりとか。

使い方

クラス定義を含んだファイルを require (include) して、内部に定義されている関数を呼び出します。 このクラスに含まれている全ての関数は、static に呼び出すことができますので、new でインスタンスを生成する必要はありません。

<?php
    require_once(dirname(__FILE__) . '/MobilePhoneAddress.class.php');
    
    $result = MobilePhoneAddress::GetCarrier();
    var_dump($result);
?>

このように呼び出すと、現在アクセスしているクライアントのキャリアを判定して $result に格納します。 定義されている関数については別項目を参照してください。

関数

公開関数のみ。 非公開関数は使用しないでください。

GetCarrier

/**
 * キャリア名を取得する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  string              AU, DoCoMo, Softbank, Willcom のいずれか。判定できなければ false
 */

function GetCarrier($ipaddr = NULL) { ... }

IsAU

/**
 * AU の端末か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool                AU の端末と思われれば true、そうでなければ false
 *
 * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
 * @see     http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html
 */

function IsAU($ipaddr = NULL) { ... }

IsDoCoMo

/**
 * DoCoMo の端末か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool                DoCoMo の端末と思われれば true、そうでなければ false
 *
 * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
 * @see     http://www.nttdocomo.co.jp/service/imode/make/content/ip/
 */

function IsDoCoMo($ipaddr = NULL) { ... }

IsDoCoMoFullBrowser

/**
 * DoCoMo の端末(フルブラウザ)か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool                DoCoMo の端末と思われれば true、そうでなければ false
 *
 * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
 * @see     http://www.nttdocomo.co.jp/service/imode/make/content/ip/
 */

function IsDoCoMoFullBrowser($ipaddr = NULL) { ... }

IsDoCoMoAll

/**
 * DoCoMo の端末(i-mode、フルブラウザは問わない)か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool    DoCoMo の端末と思われれば true、そうでなければ false
 *
 * @sa  IsDoCoMo, IsDoCoMoFullBrowser
 */

function IsDoCoMoAll($ipaddr = NULL) { ... }

IsSoftbank

/**
 * Softbank の端末か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool                Softbank の端末と思われれば true、そうでなければ false
 *
 * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
 * @see     http://developers.softbankmobile.co.jp/dp/tech_svc/web/ip.php
 */

function IsSoftbank($ipaddr = NULL) { ... }

IsWillcom

/**
 * Willcom の端末か判定する
 *
 * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
 * @return  bool                Willcom の端末と思われれば true、そうでなければ false
 *
 * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
 * @see     http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/ip/
 */

function IsWillcom($ipaddr = NULL) { ... }

注意事項

判定用のデータベースは、各キャリアから提供されているデータを用いています。 当サイトおよび当クラスではその正当性を保証しません。 また、利用の際は各自の責任において各サイトをチェックし、アドレスの更新が行われていないか確認してください。

※各キャリアのサイトが更新された場合でも、当クラスを更新する保証はありません。 その際は、追加または削除されたアドレスブロックを編集してください。 ブロックの定義は、各関数の先頭付近にあります。

未反映情報

WILLCOM

2007/4/23 に帯域が 3 つ追加されています。 現在のところサイト上のデータには反映してありません。 WILLCOM に対して判定を行う場合、次のアドレス帯域を追加してご使用ください。(たったの 3 アドレスですが…。)

なお、これらのアドレスは、同日にサービスが開始された新高速化サービスを利用した場合に使用されるアドレスのようです。 (当然ですが、その目的のみに使われる保証はありません。あくまで WILLCOM のアドレス帯域に過ぎません)

ライセンス

このクラスは(修正済み) BSD ライセンスで提供します。 原作者表記のある限り、自由に利用いただいて結構です。

メンテナ

このクラスは、HiNa がメンテナンスしていますが、動作等について保証するものではありません。 また、ライセンスは上述の通りで、利用時に報告する必要は全くありませんが一言いってもらえると大変喜びます。

なお、この関数についての連絡にはメールを送るよりも、日記のコメント機能(リンク先は関連の日記エントリ)を利用したほうが確実に目に入ります。 メールはご他聞に漏れず、spam メールであふれています。

ダウンロード

ダウンロード (tar.gz / 2.79kB / SHA1SUM: 8d88fa8890ff92458b7130def2357564f6b6c87d)

ソースコード

<?php
    // Language:        Japanese
    // Text-Encoded:    UTF-8
    
    /**
     * IP アドレスが携帯電話端末のものか判定するクラス
     *
     * @version     Release 1
     * @date        2007/04/12 (JST)
     * @author      HiNa (hina@bouhime.com)
     * @copyright   Copyright (C) 2007 by HiNa (hina@bouhime.com)
     *
     * @warning     このクラスでの判定結果が正しい保証はありません。
     *              必ず各社 IP アドレス記載ページの注意書きを理解してから使用してください。
     */

    class MobilePhoneAddress {
        /**
         * キャリア名を取得する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  string              AU, DoCoMo, Softbank, Willcom のいずれか。判定できなければ false
         */

        function GetCarrier($ipaddr = NULL) {
            if(MobilePhoneAddress::IsAU($ipaddr)) {
                return 'AU';
            } elseif(MobilePhoneAddress::IsDoCoMoAll($ipaddr)) {
                return 'DoCoMo';
            } elseif(MobilePhoneAddress::IsSoftbank($ipaddr)) {
                return 'Softbank';
            } elseif(MobilePhoneAddress::IsWillcom($ipaddr)) {
                return 'Willcom';
            }
            return false;
        }
        
        /**
         * AU の端末か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool                AU の端末と思われれば true、そうでなければ false
         *
         * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
         * @see     http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html
         */

        function IsAU($ipaddr = NULL) {
            $blocks = array(
                '210.169.40.0/24',
                '210.196.3.192/26',
                '210.196.5.192/26',
                '210.230.128.0/24',
                '210.230.141.192/26',
                '210.234.105.32/29',
                '210.234.108.64/26',
                '210.251.1.192/26',
                '210.251.2.0/27',
                '211.5.1.0/24',
                '211.5.2.128/25',
                '211.5.7.0/24',
                '218.222.1.0/24',
                '61.117.0.0/24',
                '61.117.1.0/24',
                '61.117.2.0/26',
                '61.202.3.0/24',
                '219.108.158.0/26',
                '219.125.148.0/24',
                '222.5.63.0/24',
                '222.7.56.0/24',
                '222.5.62.128/25',
                '222.7.57.0/24',
                '59.135.38.128/25',
                '219.108.157.0/25',
                '219.125.151.128/25'
            );
            return MobilePhoneAddress::_InAddressBlock($ipaddr, $blocks);
        }
        
        /**
         * DoCoMo の端末か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool                DoCoMo の端末と思われれば true、そうでなければ false
         *
         * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
         * @see     http://www.nttdocomo.co.jp/service/imode/make/content/ip/
         */

        function IsDoCoMo($ipaddr = NULL) {
            $addresses = array(
                '210.153.84.0/24',
                '210.136.161.0/24',
                '210.153.86.0/24'
            );
            return MobilePhoneAddress::_InAddressBlock($ipaddr, $addresses);
        }
        
        /**
         * DoCoMo の端末(フルブラウザ)か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool                DoCoMo の端末と思われれば true、そうでなければ false
         *
         * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
         * @see     http://www.nttdocomo.co.jp/service/imode/make/content/ip/
         */

        function IsDoCoMoFullBrowser($ipaddr = NULL) {
            $addresses = array('210.153.87.0/24');
            return MobilePhoneAddress::_InAddressBlock($ipaddr, $addresses);
        }
        
        /**
         * DoCoMo の端末(i-mode、フルブラウザは問わない)か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool    DoCoMo の端末と思われれば true、そうでなければ false
         *
         * @sa  IsDoCoMo, IsDoCoMoFullBrowser
         */

        function IsDoCoMoAll($ipaddr = NULL) {
            return MobilePhoneAddress::IsDoCoMo($ipaddr) ||
                   MobilePhoneAddress::IsDoCoMoFullBrowser($ipaddr);
        }
        
        /**
         * Softbank の端末か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool                Softbank の端末と思われれば true、そうでなければ false
         *
         * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
         * @see     http://developers.softbankmobile.co.jp/dp/tech_svc/web/ip.php
         */

        function IsSoftbank($ipaddr = NULL) {
            $addresses = array(
                '202.179.204.0/24',
                '202.253.96.248/29',
                '210.146.7.192/26',
                '210.146.60.192/26',
                '210.151.9.128/26',
                '210.169.130.112/29',
                '210.169.130.120/29',
                '210.169.176.0/24',
                '210.175.1.128/25',
                '210.228.189.0/24',
                '211.8.159.128/25'
            );
            return MobilePhoneAddress::_InAddressBlock($ipaddr, $addresses);
        }
        
        /**
         * Willcom の端末か判定する
         *
         * @param   string  $ipaddr     判定する IP アドレス。省略すると現在のクライアント
         * @return  bool                Willcom の端末と思われれば true、そうでなければ false
         *
         * @warning 2007/4 現在の IP アドレス。最新版を常に確認のこと。
         * @see     http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/ip/
         */

        function IsWillcom($ipaddr = NULL) {
            $addresses = array(
                '61.198.142.0/24',
                '219.108.14.0/24',
                '61.198.161.0/24',
                '219.108.0.0/24',
                '61.198.249.0/24',
                '219.108.1.0/24',
                '61.198.250.0/24',
                '219.108.2.0/24',
                '61.198.253.0/24',
                '219.108.3.0/24',
                '61.198.254.0/24',
                '219.108.4.0/24',
                '61.198.255.0/24',
                '219.108.5.0/24',
                '61.204.3.0/25',
                '219.108.6.0/24',
                '61.204.4.0/24',
                '221.119.0.0/24',
                '61.204.6.0/25',
                '221.119.1.0/24',
                '125.28.4.0/24',
                '221.119.2.0/24',
                '125.28.5.0/24',
                '221.119.3.0/24',
                '125.28.6.0/24',
                '221.119.4.0/24',
                '125.28.7.0/24',
                '221.119.5.0/24',
                '125.28.8.0/24',
                '221.119.6.0/24',
                '211.18.235.0/24',
                '221.119.7.0/24',
                '211.18.238.0/24',
                '221.119.8.0/24',
                '211.18.239.0/24',
                '221.119.9.0/24',
                '125.28.11.0/24',
                '125.28.13.0/24',
                '125.28.12.0/24',
                '125.28.14.0/24',
                '125.28.2.0/24',
                '125.28.3.0/24',
                '211.18.232.0/24',
                '211.18.233.0/24',
                '211.18.236.0/24',
                '211.18.237.0/24',
                '125.28.0.0/24',
                '125.28.1.0/24',
                '61.204.0.0/24',
                '210.168.246.0/24',
                '210.168.247.0/24',
                '219.108.7.0/24',
                '61.204.2.0/24',
                '61.204.5.0/24',
                '61.198.129.0/24',
                '61.198.140.0/24',
                '61.198.141.0/24',
                '125.28.15.0/24',
                '61.198.165.0/24',
                '61.198.166.0/24',
                '61.198.168.0/24',
                '61.198.169.0/24',
                '61.198.170.0/24',
                '61.198.248.0/24',
                '125.28.16.0/24',
                '125.28.17.0/24',
                '211.18.234.0/24',
                '219.108.8.0/24',
                '219.108.9.0/24',
                '219.108.10.0/24'
            );
            return MobilePhoneAddress::_InAddressBlock($ipaddr, $addresses);
        }
        
        /**
         * @private
         *
         * マスクビット数からマスクへ変換する
         *
         * @param   integer     $bits   ビット数(0z)
         * @return  integer             マスク値
         */

        function _Bitnum2Mask($bits) {
            return (0xFFFFFFFF << (32 - $bits)) & 0xFFFFFFFF;
        }
        
        /**
         * @private
         *
         * 現在のクライアントの IP アドレスを取得
         *
         * @return  string  接続中クライアントの IP アドレス。取得できなければ NULL
         */

        function _CurrentIPAddress() {
            global $_SERVER;
            return is_array($_SERVER) && array_key_exists('REMOTE_ADDR', $_SERVER) ?
                        $_SERVER['REMOTE_ADDR'] :
                        NULL;
        }
        
        /**
         * @private
         *
         * 指定された IP アドレスがアドレスブロックに含まれるか判定する
         * (_IsSameAddressBlock のラッパ)
         *
         * @param   string  $ipaddress  IPv4 形式アドレス。NULL で現在のクライアント
         * @param   mixed   $block      IPv4 形式で、"/" を用いたネットマスク表現のブロック。配列可
         * @return  bool                ブロックに含まれれば true、そうでなければ false
         */

        function _InAddressBlock($ipaddress, &$block) {
            if(is_null($ipaddress)) {
                $ipaddress = MobilePhoneAddress::_CurrentIPAddress();
            }
            if(is_array($block)) {
                foreach($block as $b) {
                    if(MobilePhoneAddress::_InAddressBlock($ipaddress, $b)) {
                        return true;
                    }
                }
                return false;
            }
            return MobilePhoneAddress::_IsSameAddressBlock($ipaddress, $block);
        }
        
        /**
         * @private
         *
         * ip2long 関数のラッパ
         * PHP4/PHP5 共に失敗時には FALSE を返す
         *
         * @param   string  $ipaddress  IPv4 形式の IP アドレス
         * @return  integer             Long 形式に変換されたアドレス。失敗時 FALSE
         */

        function _Ip2Long($ipaddress) {
            $long = ip2long($ipaddress);
            return ($long == -1 || $long === false) ? false : $long;
        }
        
        /**
         * @private
         *
         * 指定された IP アドレスがアドレスブロックに含まれるか判定する
         *
         * @param   string  $ipaddress  IPv4 形式の IP アドレス
         * @param   string  $block      IPv4 形式で、"/" を用いたネットマスク表現のブロック
         * @return  bool                同一ブロックであれば true、そうでなければ false
         */

        function _IsSameAddressBlock($ipaddress, $block) {
            if(! preg_match('/^(\d+\.\d+\.\d+\.\d+)\/(\d+)$/', $block, $match)) {
                if(preg_match('/^\d+\.\d+\.\d+\.\d+$/', $block)) {
                    // $block にネットマスク指定のないアドレスが渡された場合、
                    // 32 ビットマスクと仮定して判定。
                    // 本来、わざわざ再帰するまでもないが、一応。
                    // そもそも全うにこのクラスを使う限りこのルートは通らないはず。
                    return MobilePhoneAddress::_IsSameAddressBlock($ipaddress, $block . '/32');
                }
                return false;
            }
            
            $netmaskbit = (int)$match[2];
            if(! (0 <= $netmaskbit && $netmaskbit <= 32)) {
                // ネットマスクサイズ異常
                return false;
            }
            
            $mask = MobilePhoneAddress::_Bitnum2Mask($netmaskbit);
            $ipaddress_long = MobilePhoneAddress::_IP2Long($ipaddress);
            $netblock_long  = MobilePhoneAddress::_IP2Long($match[1]);
            
            if($ipaddress_long === false || $netblock_long === false) {
                return false;
            }
            
            return ($ipaddress_long & $mask) == ($netblock_long & $mask);
        }
    }
?>