當使用流動裝置傳取桌面版的網頁時,會自動移至流動裝置版的分頁
判斷瀏覽器是否流動裝置便需要先觀察 User Agent……
當使用網頁瀏覽器時,會提供稱為 User Agent 的訊息,訊息通常會包括:
使用者使用的作業系統名稱、作業系統版本、瀏覽器名稱、瀏覽器版本、排版引擎名稱、排版引擎版本
當能力分折 User Agent 的資料,便可以獲得使用者的作業系統名稱從判斷是否流動裝置,便可以轉移至合適的網頁版本
甚至可以獲得使用者的瀏覽器的預設語言,當使用存取網頁時讓網頁設換至相對語言,讓網頁更加人性化
閣下可以參巧以下程序碼
或到以下連結 https://bitbucket.org/hkgoldenmra/php-user-agent-parser
或利用 git 下載專案
1 | git clone https: //hkgoldenmra @bitbucket.org /hkgoldenmra/php-user-agent-parser .git |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | <?php class UserAgentParser{ const VERSION_FORMAT = '(?:[0-9A-Za-z]+)(?:[\.\-\_][0-9A-Za-z]+)*\+?' ; // add more windows version here private static $WINDOWS_VERSIONS = array ( 'ce' => 'CE' , '95' => '95' , '98' => '98' , '4.0' => 'NT 4.0' , '5.0' => '2000' , '5.1' => 'XP' , '5.2' => '2003' , '6.0' => 'VISTA' , '6.1' => '7' , '6.2' => '8' , ); // add more samsung galaxy versio here private static $SAMSUNG_GALAXY_VERSIONS = array ( 'i8150' => 'W' , 'i8160' => 'Ace 2' , 'i8190n' => 'S3 Mini' , 'i8530' => 'Beam' , 'i8730' => 'Express' , 'i9001' => 'S+' , 'i9003' => 'S' , 'i9070' => 'S Advance' , 'i9100' => 'S2' , 'i9103' => 'R' , 'i9105p' => 'S2+' , 'i9190' => 'S4 Mini' , 'i9192' => 'S4 Mini Duo' , 'i9195' => 'S4 Mini LTE' , 'i9210' => 'S2 LTE' , 'i9250' => 'Nexus' , 'i9295' => 'S4 Active' , 'i9300' => 'S3' , 'i9305' => 'S3 LTE' , 'i9500' => 'S4' , 'i9505' => 'S4 LTE' , 'n7000' => 'Note' , 'n7100' => 'Note 2' , 'n7105' => 'Note 2 LTE' , 'p6200' => 'Tab 7.0+' , 'p7500' => 'Tab 10.1' , 's5301' => 'Pocket' , 's5360' => 'Y' , 's5380' => 'Ace' , 's5380d' => 'Wave Y' , 's5660' => 'Gio' , 's6102' => 'Y Duos' , 's6500d' => 'Mini 2' , 's6802' => 'Ace Duos' , 's7500' => 'Ace+' , 's7562' => 'S Duos' , 'nexus' => 'Nexus' , ); // add more mobile os here private static $MOBILE_OS_NAMES = array ( 'blackberry(?: (%s))?' => 'BlackBerry' , 'meego(?: (%s))?' => 'Nokia MeeGo' , 'ipod.*?cpu.*?os(?: (%s))?' => 'iPod' , 'iphone.*?cpu.*?os(?: (%s))?' => 'iPhone' , 'ipad.*?cpu.*?os(?: (%s))?' => 'iPad' , 'sonyericsson(%s)?' => 'Sony Xperia' , 'htc sensation(?: (%s))?' => 'HTC Sensation' , '(?:(?:galaxy)|(?:gt))(?:[ \-](%s))?' => 'Samsung Galaxy' , 'nexus one(?: (%s))?' => 'Nexus One' , 'android(?: (%s))?' => 'Android' , ); // add more os here private static $OS_NAMES = array ( 'windows phone os(?: (%s))?' => 'Windows Phone OS' , '(?:(?:winnt)|(?:windows(?: nt)?))(?: (%s))?' => 'Windows' , 'mac os x(?: (%s))?' => 'Mac OS X' , '(?:mac(?:intosh)|(?:_powerpc))(?: (%s))?' => 'Macintosh' , 'linux mint(?:\/(%s))?' => 'Linux Mint' , 'ubuntu(?:\/(%s))?' => 'Ubuntu' , 'debian(?:\/(%s))?' => 'Debian' , '(?:mandriva(?: linux)?)(?: (%s))?' => 'Mandriva' , 'fedora(?: (%s))?' => 'Fedora' , 'oracle(?: (%s))?' => 'Oracle' , 'gentoo(?: (%s))?' => 'Gentoo' , 'freebsd(?: (%s))?' => 'FreeBSD' , 'openbsd(?: (%s))?' => 'OpenBSD' , '(?:s(?:olaris)|(?:unos))(?: (%s))?' => 'Solaris' , '(?:(?:linux)|(?:x11))(?: (%s))?' => 'GNU/Linux' , ); // add more mobile browser here private static $MOBILE_BROWSER_NAMES = array ( 'opera.*mini.*version(?:\/(%s))?' => 'Opera Mini' , 'opera.*mobi.*version(?:\/(%s))?' => 'Opera Mobile' , 'dolphin(?:\/(%s))?' => 'Dolphin Browser' , 'nokiabrowser(?:\/(%s))?' => 'Nokia Browser' , 'iemobile(?:\/(%s))?' => 'Internet Explorer Mobile' , 'fennec(?:\/(%s))?' => 'Fennec' , 'android.*version(?:\/(%s))?' => 'Android Browser' , 'crios(?:\/(%s))?' => 'CriOS' , '(?:ip.*cpu.*os.*version(?:\/(%s))?)' => 'Mobile Safari' , '(?:ip.*cpu.*os.*mobile(?:\/(%s))?)' => 'Mobile Safari' , 'dalvik(?:\/(%s))?' => 'Dalvik' , ); // add more browser here private static $BROWSER_NAMES = array ( 'opera.*version(?:\/(%s))?' => 'Opera' , 'maxthon(?:\ (%s))?' => 'Maxthon' , 'msie(?:\ (%s))?' => 'Internet Explorer' , 'iceweasel(?:\/(%s))?' => 'Iceweasel' , '(?:n(?:etscape)|(?:avigator))(?:\/(%s))?' => 'Netscape Navigator' , 'thunderbird(?:\/(%s))?' => 'Thunderbird' , 'thunderbrowse(?:\/(%s))?' => 'ThunderBrowse' , 'firefox(?:\/(%s))?' => 'Firefox' , 'google earth(?:\/(%s))?' => 'Google Earth' , 'midori(?:\/(%s))?' => 'Midori' , 'iron(?:\/(%s))?' => 'Iron' , 'chromium(?:\/(%s))?' => 'Chromium' , 'chrome(?:\/(%s))?' => 'Chrome' , 'epiphany(?:\/(%s))?' => 'Epiphany' , 'konqueror(?:\/(%s))?' => 'Konqueror' , 'version(?:\/(%s))?\ safari' => 'Safari' , 'netsurf(?:\/(%s))?' => 'NetSurf' , 'wget(?:\/(%s))?' => 'Wget' , 'dillo(?:\/(%s))?' => 'Dillo' , ); // add more robot here private static $ROBOT_NAMES = array ( 'baiduspider(?:\/(%s))?' => 'Baidu Spider' , 'bingbot(?:\/(%s))?' => 'Bing Bot' , 'googlebot(?:\/(%s))?' => 'Google Bot' , 'ia\_archiver(?:\/(%s))?' => 'Internet Archive' , ); // add more layout engine here private static $LAYOUT_NAMES = array ( 'trident(?:\/(%s))?' => 'Trident' , '(?:apple)?webkit(?:\/(%s))?' => 'WebKit' , 'khtml(?:\/(%s))?' => 'KHTML' , 'gecko(?:\/(%s))?' => 'Gecko' , 'presto(?:\/(%s))?' => 'Presto' , ); private $user_agent = '' ; private $colored_user_agent = '' ; private $default_language = '' ; private $is_mobile = false; private $is_robot = false; private $os_name = '' ; private $os_version = '' ; private $browser_name = '' ; private $browser_version = '' ; private $layout_name = '' ; private $layout_version = '' ; /* the parent must under child in order */ public static final function MOBILE_OS_NAMES(){ return self:: $MOBILE_OS_NAMES ; } public static final function OS_NAMES(){ return self:: $OS_NAMES ; } public static final function MOBILE_BROWSER_NAMES(){ return self:: $MOBILE_BROWSER_NAMES ; } public static final function BROWSER_NAMES(){ return self:: $BROWSER_NAMES ; } public static final function ROBOT_NAMES(){ return self:: $ROBOT_NAMES ; } public static final function LAYOUT_NAMES(){ return self:: $LAYOUT_NAMES ; } public function get_user_agent(){ return $this ->user_agent; } public function get_colored_user_agent(){ return $this ->colored_user_agent; } public function get_default_language(){ return $this ->default_language; } public function is_robot(){ return $this ->is_robot; } public function is_mobile(){ return $this ->is_mobile; } public function get_os_name(){ return $this ->os_name; } public function get_os_version(){ return $this ->os_version; } public function get_browser_name(){ return $this ->browser_name; } public function get_browser_version(){ return $this ->browser_version; } public function get_layout_name(){ return $this ->layout_name; } public function get_layout_version(){ return $this ->layout_version; } private function set_user_agent( $user_agent ){ if ( strlen ( $user_agent ) === 0){ $user_agent = $_SERVER [ 'HTTP_USER_AGENT' ]; } $this ->colored_user_agent = $this ->user_agent = $user_agent ; } private function set_default_language(){ $matches = array (); if (preg_match( '/^(..(?:\-..))[\,\;]?/i' , $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ], $matches ) > 0){ $this ->default_language = preg_replace( '/[\-]/' , '_' , strtolower ( $matches [1])); } } private function set_name_version( $array , & $name , & $version , $color , $check_is_robot = false, $check_is_mobile = false){ $matches = array (); foreach ( $array as $k => $v ){ $regex = sprintf( '/(?:%s)/i' , sprintf( $k , self::VERSION_FORMAT)); if (preg_match( $regex , $this ->user_agent, $matches ) > 0){ $name = $v ; $this ->colored_user_agent = str_replace ( $matches [0], sprintf( '<span style="color:%s;">%s</span>' , $color , $matches [0]), $this ->colored_user_agent); if ( count ( $matches ) > 1){ $version = preg_replace( '/[_\-]/i' , '.' , $matches [1]); switch ( $v ){ case 'Windows' : { $version = self:: $WINDOWS_VERSIONS [ $version ]; } break ; case 'Samsung Galaxy' : { $version = self:: $SAMSUNG_GALAXY_VERSIONS [ $version ]; } break ; } } $this ->is_robot = $check_is_robot ; $this ->is_mobile = $check_is_mobile ; break ; } } } public function __construct( $user_agent = '' ){ $this ->set_default_language(); $this ->set_user_agent( '' . $user_agent ); $this ->set_name_version(self::ROBOT_NAMES(), $this ->browser_name, $this ->browser_version, 'blue' , true, $this ->is_mobile()); if (! $this ->is_robot()){ $this ->set_name_version(self::MOBILE_BROWSER_NAMES(), $this ->browser_name, $this ->browser_version, 'blue' , $this ->is_robot(), true); if (! $this ->is_mobile()){ $this ->set_name_version(self::BROWSER_NAMES(), $this ->browser_name, $this ->browser_version, 'blue' , $this ->is_robot(), $this ->is_mobile()); } } $this ->set_name_version(self::LAYOUT_NAMES(), $this ->layout_name, $this ->layout_version, 'green' , $this ->is_robot(), $this ->is_mobile()); if (! $this ->is_robot()){ if (! $this ->is_mobile()){ $this ->set_name_version(self::OS_NAMES(), $this ->os_name, $this ->os_version, 'red' , $this ->is_robot(), $this ->is_mobile()); } else { $this ->set_name_version(self::MOBILE_OS_NAMES(), $this ->os_name, $this ->os_version, 'red' , $this ->is_robot(), true); } } } } ?> |
只需要利用 regex 尋找對應該的名稱就完成操作,例如作業系統
使用 Linux 其 user agent 會使用 x11 或 Linux 的代號,可以利用
1 | /(x11|linux)/i |
在 PHP 的 preg_match 操作上,capturing group 會將資料傳回給第三個參數,相反 non-capturing group 則不會傳回
善用 non-capturing group 可以避免收集不必要的資料,例如在下的 regex 經常出現如
1 | /(?:(?:(?:linux)|(?:x11))(?:\ ((?:[0-9]+)(?:[\.\-\_][0-9]+)*))?)/i |
而需分析版本的 ((?:[0-9]+)(?:[\.\-\_][0-9]+)*))? 則使用 capturing group
另外還需要注意編程次序
一般程式碼由於會以上至下方式閱讀資料,若果某作業系統、瀏覽器,是另一個作業系統、瀏覽器的子集、衍生版
子集的程式碼必須比其父項編排得前,例如作業系統
Linux Mint 是 Ubuntu 的子集,Ubuntu 是 Debian 的子集,Debian 的 Linux 的子集
程式碼便必須以 Linux Mint, Ubuntu, Debian, Linux 或類似的次序編排
否則父項比子集次序編排為前時,子集將不會被閱讀
作者已經移除這則留言。
回覆刪除請問這樣怎麼使用呢
回覆刪除