PHPに惚れました

今でも多分惚れてます。

PHPで携帯電話からのアクセスかを判別するスクリプト書いた

携帯からのみアクセスを許したいページを作りたいとき、何で判別していますか?

UserAgentで判別。それだけではいけません。

UserAgentなんて簡単に偽装されてしまいます。

そこで、IPアドレス帯域を検査することで大丈夫。

携帯電話は各キャリアのサーバを経由してWebサーバにアクセスします。
その際、Webサーバに対して各キャリアのサーバのIPアドレスがリクエスト要求元のIPアドレスとして通知されます。

これは偽装しようが無いので信頼できる情報です。

下準備

2つのPEARパッケージのインストールが必要です。
インストールされてない方はインストールして下さい。

インクルードパスの設定なども各自。

ソース

<?php
class MobileCheck{
	private $zone;

	private function SetZone($env){
		/* IP帯域の設定 */
		if($env === 'docomo'){
			//i-mode(NTT DoCoMo)のIPアドレス帯域を設定
			//更新日時:2010-03-10
			//http://www.nttdocomo.co.jp/service/imode/make/content/ip/index.html
			$this->zone[0] = '210.153.84.0/24';
			$this->zone[1] = '210.136.161.0/24';
			$this->zone[2] = '210.153.86.0/24';
			$this->zone[3] = '124.146.174.0/24';
			$this->zone[4] = '124.146.175.0/24';
		}elseif($env === 'au'){
			//EZWeb(au)のIPアドレス帯域を設定
			//更新日時:2010-03-10
			//http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html
			$this->zone[0] = '210.230.128.224/28';
			$this->zone[1] = '121.111.227.160/27';
			$this->zone[2] = '61.117.1.0/28';
			$this->zone[3] = '219.108.158.0/27';
			$this->zone[4] = '219.125.146.0/28';
			$this->zone[5] = '61.117.2.32/29';
			$this->zone[6] = '61.117.2.40/29';
			$this->zone[7] = '219.108.158.40/29';
			$this->zone[8] = '219.125.148.0/25';
			$this->zone[9] = '222.5.63.0/25';
			$this->zone[10] = '222.5.63.128/25';
			$this->zone[11] = '222.5.62.128/25';
			$this->zone[12] = '59.135.38.128/25';
			$this->zone[13] = '219.108.157.0/25';
			$this->zone[14] = '219.125.145.0/25';
			$this->zone[15] = '121.111.231.0/25';
			$this->zone[16] = '121.111.227.0/25';
			$this->zone[17] = '118.152.214.192/26';
			$this->zone[18] = '118.159.131.0/25';
			$this->zone[19] = '118.159.133.0/25';
			$this->zone[20] = '118.159.132.160/27';
			$this->zone[21] = '111.86.142.0/26';
			$this->zone[22] = '111.86.141.64/26';
			$this->zone[23] = '111.86.141.128/26';
			$this->zone[24] = '111.86.141.192/26';
		}elseif($env === 'softbank'){
			//Yahoo!ケータイ(SoftBank)のIPアドレス帯域を設定
			//更新日時:2010-03-10
			//http://developers.softbankmobile.co.jp/dp/tech_svc/web/ip.php
			$this->zone[0] = '123.108.236.0/24';
			$this->zone[1] = '123.108.237.0/27';
			$this->zone[2] = '202.179.204.0/24';
			$this->zone[3] = '202.253.96.224/27';
			$this->zone[4] = '210.146.7.192/26';
			$this->zone[5] = '210.146.60.192/26';
			$this->zone[6] = '210.151.9.128/26';
			$this->zone[7] = '210.175.1.128/25';
			$this->zone[8] = '211.8.159.128/25';
		}elseif($env === 'willcom'){
			//AIR-EDGE PHONE(WILLCOM)のIPアドレス帯域を設定
			//更新日時:2010-03-10
			//http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/ip/
			$this->zone[0] = '61.198.128.0/24';
			$this->zone[1] = '61.198.129.0/24';
			$this->zone[2] = '61.198.130.0/24';
			$this->zone[3] = '61.198.131.0/24';
			$this->zone[4] = '61.198.132.0/24';
			$this->zone[5] = '61.198.133.0/24';
			$this->zone[6] = '61.198.134.0/24';
			$this->zone[7] = '61.198.135.0/24';
			$this->zone[8] = '61.198.136.0/24';
			$this->zone[9] = '61.198.137.0/24';
			$this->zone[10] = '61.198.138.100/32';
			$this->zone[11] = '61.198.138.101/32';
			$this->zone[12] = '61.198.138.102/32';
			$this->zone[13] = '61.198.138.103/32';
			$this->zone[14] = '61.198.139.0/29';
			$this->zone[15] = '61.198.139.128/27';
			$this->zone[16] = '61.198.139.160/28';
			$this->zone[17] = '61.198.140.0/24';
			$this->zone[18] = '61.198.141.0/24';
			$this->zone[19] = '61.198.142.0/24';
			$this->zone[20] = '61.198.143.0/24';
			$this->zone[21] = '61.198.160.0/24';
			$this->zone[22] = '61.198.161.0/24';
			$this->zone[23] = '61.198.162.0/24';
			$this->zone[24] = '61.198.163.0/24';
			$this->zone[25] = '61.198.164.0/24';
			$this->zone[26] = '61.198.165.0/24';
			$this->zone[27] = '61.198.166.0/24';
			$this->zone[28] = '61.198.168.0/24';
			$this->zone[29] = '61.198.169.0/24';
			$this->zone[30] = '61.198.170.0/24';
			$this->zone[31] = '61.198.171.0/24';
			$this->zone[32] = '61.198.172.0/24';
			$this->zone[33] = '61.198.173.0/24';
			$this->zone[34] = '61.198.174.0/24';
			$this->zone[35] = '61.198.175.0/24';
			$this->zone[36] = '61.198.248.0/24';
			$this->zone[37] = '61.198.249.0/24';
			$this->zone[38] = '61.198.250.0/24';
			$this->zone[39] = '61.198.251.0/24';
			$this->zone[40] = '61.198.252.0/24';
			$this->zone[41] = '61.198.253.0/24';
			$this->zone[42] = '61.198.254.0/24';
			$this->zone[43] = '61.198.255.0/24';
			$this->zone[44] = '61.204.0.0/24';
			$this->zone[45] = '61.204.2.0/24';
			$this->zone[46] = '61.204.3.0/25';
			$this->zone[47] = '61.204.3.128/25';
			$this->zone[48] = '61.204.4.0/24';
			$this->zone[49] = '61.204.5.0/24';
			$this->zone[50] = '61.204.6.0/25';
			$this->zone[51] = '61.204.6.128/25';
			$this->zone[52] = '61.204.7.0/25';
			$this->zone[53] = '61.204.92.0/24';
			$this->zone[54] = '61.204.93.0/24';
			$this->zone[55] = '61.204.94.0/24';
			$this->zone[56] = '61.204.95.0/24';
			$this->zone[57] = '114.20.49.0/24';
			$this->zone[58] = '114.20.50.0/24';
			$this->zone[59] = '114.20.51.0/24';
			$this->zone[60] = '114.20.52.0/24';
			$this->zone[61] = '114.20.53.0/24';
			$this->zone[62] = '114.20.54.0/24';
			$this->zone[63] = '114.20.55.0/24';
			$this->zone[64] = '114.20.56.0/24';
			$this->zone[65] = '114.20.57.0/24';
			$this->zone[66] = '114.20.58.0/24';
			$this->zone[67] = '114.20.59.0/24';
			$this->zone[68] = '114.20.60.0/24';
			$this->zone[69] = '114.20.61.0/24';
			$this->zone[70] = '114.20.62.0/24';
			$this->zone[71] = '114.20.63.0/24';
			$this->zone[72] = '114.20.64.0/24';
			$this->zone[73] = '114.20.65.0/24';
			$this->zone[74] = '114.20.66.0/24';
			$this->zone[75] = '114.20.67.0/24';
			$this->zone[76] = '114.21.255.0/27';
			$this->zone[77] = '125.28.0.0/24';
			$this->zone[78] = '125.28.1.0/24';
			$this->zone[79] = '125.28.15.0/24';
			$this->zone[80] = '125.28.16.0/24';
			$this->zone[81] = '125.28.17.0/24';
			$this->zone[82] = '125.28.2.0/24';
			$this->zone[83] = '125.28.3.0/24';
			$this->zone[84] = '125.28.4.0/24';
			$this->zone[85] = '125.28.5.0/24';
			$this->zone[86] = '125.28.8.0/24';
			$this->zone[87] = '210.168.246.0/24';
			$this->zone[88] = '210.168.247.0/24';
			$this->zone[89] = '210.169.92.0/24';
			$this->zone[90] = '210.169.93.0/24';
			$this->zone[91] = '210.169.94.0/24';
			$this->zone[92] = '210.169.95.0/24';
			$this->zone[93] = '210.169.96.0/24';
			$this->zone[94] = '210.169.97.0/24';
			$this->zone[95] = '210.169.98.0/24';
			$this->zone[96] = '210.169.99.0/24';
			$this->zone[97] = '211.126.192.128/25';
			$this->zone[98] = '211.18.232.0/24';
			$this->zone[99] = '211.18.233.0/24';
			$this->zone[100] = '211.18.234.0/24';
			$this->zone[101] = '211.18.235.0/24';
			$this->zone[102] = '211.18.236.0/24';
			$this->zone[103] = '211.18.237.0/24';
			$this->zone[104] = '219.108.10.0/24';
			$this->zone[105] = '219.108.11.0/24';
			$this->zone[106] = '219.108.12.0/24';
			$this->zone[107] = '219.108.13.0/24';
			$this->zone[108] = '219.108.14.0/24';
			$this->zone[109] = '219.108.15.0/24';
			$this->zone[110] = '219.108.7.0/24';
			$this->zone[111] = '219.108.8.0/24';
			$this->zone[112] = '219.108.9.0/24';
			$this->zone[113] = '221.119.0.0/24';
			$this->zone[114] = '221.119.1.0/24';
			$this->zone[115] = '221.119.2.0/24';
			$this->zone[116] = '221.119.3.0/24';
			$this->zone[117] = '221.119.4.0/24';
			$this->zone[118] = '221.119.6.0/24';
			$this->zone[119] = '221.119.7.0/24';
			$this->zone[120] = '221.119.8.0/24';
			$this->zone[121] = '221.119.9.0/24';
			$this->zone[122] = '114.20.49.0/24';
			$this->zone[123] = '114.20.50.0/24';
			$this->zone[124] = '114.20.51.0/24';
			$this->zone[125] = '114.20.52.0/24';
			$this->zone[126] = '114.20.53.0/24';
			$this->zone[127] = '114.20.54.0/24';
			$this->zone[128] = '114.20.55.0/24';
			$this->zone[129] = '114.20.56.0/24';
			$this->zone[130] = '114.20.57.0/24';
			$this->zone[131] = '114.20.58.0/24';
			$this->zone[132] = '114.20.59.0/24';
			$this->zone[133] = '114.20.60.0/24';
			$this->zone[134] = '114.20.61.0/24';
			$this->zone[135] = '114.20.62.0/24';
			$this->zone[136] = '114.20.63.0/24';
			$this->zone[137] = '114.20.64.0/24';
			$this->zone[138] = '114.20.65.0/24';
			$this->zone[139] = '114.20.66.0/24';
			$this->zone[140] = '114.20.67.0/24';
			$this->zone[141] = '114.21.255.0/27';
		}
	}//func-SetZone

	function GetZone(){
		return $this->zone;
	}

	private function CheckUA(){
		require_once ('Net/UserAgent/Mobile.php');

		$agent = Net_UserAgent_Mobile::singleton();
		/* UserAgentからキャリアを返す */
		if($agent->isDoCoMo()){
			$this->SetZone("docomo");
		}elseif($agent->isSoftbank()){
			$this->SetZone("softbank");
		}elseif($agent->isEZweb()){
			$this->SetZone("au");
		}elseif($agent->isWillcom()){
			$this->SetZone("willcom");
		}else{
			return FALSE;
		}
	}//func-CheckUA

	private function CheckIP($area){

		if($area===NULL){
			throw new Exception('帯域リストの取得に失敗');
		}

		require_once ('Net/IPv4.php');
		/* IPアドレス帯域($area)に含まれているか検査 */
		$flag = FALSE;

		foreach ($area as $value) {
			if (Net_IPv4::ipInNetwork($_SERVER["REMOTE_ADDR"], $value)) {
				$flag = TRUE;
				break;
			}
		}
		return $flag;
	}//func-CheckIP

	public function Check(){
		$ua = $this->CheckUA();
		if($ua===FALSE){
			return FALSE;
		}else{
			$zone = $this->GetZone($ua);
			return $this->CheckIP($this->GetZone());
		}
	}
}//class-MobileCheck
?>

利用方法

<?php
try{
	$mb = new MobileCheck;

	if($mb->Check()===TRUE){
		print "(mobile access)<br>携帯電話からのアクセスですね?";
	}else{
		print "(not mobile access)<br>携帯電話以外からのアクセスですね?";
	}
}catch(Exception $e){
	print $e->getMessage();
}
?>

MobileCheckクラスをインスタンス化して、Checkメソッドを呼び出すだけ。
Checkメソッドを呼び出すと、携帯と判別すればTRUE,携帯ではないと判別すればFalseが返る。

これだけ。

手法

テストした機種

(携帯として判別)

(携帯電話ではないと判別)

イーモバイルは判定対象外みたいですので無条件で携帯以外と判別されました。
スマートフォンも携帯電話ではない判別されました。