zoukankan      html  css  js  c++  java
  • 如何使用Mobile_Detect来判断访问网站的设备:安卓,平板,电脑

       1 Mobile_Detect 是一个轻量级的开源移动设备(手机)检测的 PHP Class   2 它使用 User-Agent 中的字符串,并结合 HTTP Header,来检测移动设备环境。
       3 这个设备检测的 PHP 类库最强大的地方是,它有一个非常完整的库,
       4 可以检测出所用的设备类型(包括操作类型,以及手机品牌等都能检测)和浏览器的详细信息。
       5 官方主页:http://mobiledetect.net/
       6 demo:http://demo.mobiledetect.net/
       7 完整的Mobile_Detect代码如下:
       8 [php] view plaincopy 
       9 <?php  
      10 /** 
      11  * MIT License 
      12  * =========== 
      13  * 
      14  * Permission is hereby granted, free of charge, to any person obtaining 
      15  * a copy of this software and associated documentation files (the 
      16  * "Software"), to deal in the Software without restriction, including 
      17  * without limitation the rights to use, copy, modify, merge, publish, 
      18  * distribute, sublicense, and/or sell copies of the Software, and to 
      19  * permit persons to whom the Software is furnished to do so, subject to 
      20  * the following conditions: 
      21  * 
      22  * The above copyright notice and this permission notice shall be included 
      23  * in all copies or substantial portions of the Software. 
      24  * 
      25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
      26  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
      27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
      28  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
      29  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
      30  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
      31  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
      32  * 
      33  * 
      34  * @author      Serban Ghita <serbanghita@gmail.com> 
      35  *              Victor Stanciu <vic.stanciu@gmail.com> (until v. 1.0) 
      36  * @license     MIT License https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt 
      37  * @link        Official page: http://mobiledetect.net 
      38  *              GitHub Repository: https://github.com/serbanghita/Mobile-Detect 
      39  *              Google Code Old Page: http://code.google.com/p/php-mobile-detect/ 
      40  * @version     2.6.6 
      41  */  
      42   
      43 class Mobile_Detect  
      44 {  
      45     /** 
      46      * Mobile detection type. 
      47      */  
      48     const DETECTION_TYPE_MOBILE     = 'mobile';  
      49   
      50     /** 
      51      * Extended detection type. 
      52      */  
      53     const DETECTION_TYPE_EXTENDED   = 'extended';  
      54   
      55     /** 
      56      * A frequently used regular expression to extract version #s. 
      57      */  
      58     const VER                       = '([w._+]+)';  
      59   
      60     /** 
      61      * Top-level device. 
      62      */  
      63     const MOBILE_GRADE_A            = 'A';  
      64   
      65     /** 
      66      * Mid-level device. 
      67      */  
      68     const MOBILE_GRADE_B            = 'B';  
      69   
      70     /** 
      71      * Low-level device. 
      72      */  
      73     const MOBILE_GRADE_C            = 'C';  
      74   
      75     /** 
      76      * Stores the version number of the current release. 
      77      * @var array 
      78      */  
      79     protected $scriptVersion = '2.6.6';  
      80   
      81     /** 
      82      * The User-Agent HTTP header is stored in here. 
      83      * @var string 
      84      */  
      85     protected $userAgent = null;  
      86   
      87     /** 
      88      * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. 
      89      * @var array 
      90      */  
      91     protected $httpHeaders = array();  
      92   
      93     /** 
      94      * All the rules combined. 
      95      * @var array 
      96      */  
      97     protected $mobileDetectionRules = null;  
      98   
      99     /** 
     100      * The rules, but extended. 
     101      * @var array 
     102      */  
     103     protected $mobileDetectionRulesExtended = null;  
     104   
     105     /** 
     106      * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED. 
     107      * 
     108      * @var string 
     109      */  
     110     protected $detectionType = self::DETECTION_TYPE_MOBILE;  
     111   
     112     /** 
     113      * List of mobile devices (phones). 
     114      * 
     115      * @var array 
     116      */  
     117     protected $phoneDevices = array(  
     118         'iPhone'        => 'iPhone.*Mobile|iPod', // |iTunes  
     119         'BlackBerry'    => 'BlackBerry|BB10|rim[0-9]+',  
     120         'HTC'           => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*EVO',  
     121         'Nexus'         => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',  
     122         // @todo: Is 'Dell Streak' a tablet or a phone? ;)  
     123         'Dell'          => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|001DL|101DL|GS01',  
     124         'Motorola'      => 'Motorola|Droid.*Build|DROIDX|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT909|XT910|XT912|XT928',  
     125         'Samsung'       => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535',  
     126         'LG'            => 'LG;|(LG|LG-)?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999)',  
     127         'Sony'          => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h',  
     128         'Asus'          => 'Asus.*Galaxy|PadFone.*Mobile',  
     129         // @ref: http://www.micromaxinfo.com/mobiles/smartphones  
     130         // Added because the codes might conflict with Acer Tablets.  
     131         'Micromax'      => 'Micromax.*(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)',  
     132         'Palm'          => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.  
     133         'Vertu'         => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)  
     134         // @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)  
     135         // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.  
     136         'Pantech'       => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',  
     137         // @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.  
     138         'Fly'           => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',  
     139         // Added simvalley mobile just for fun. They have some interesting devices.  
     140         // @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html  
     141         'SimValley'     => '(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)',  
     142         // @Tapatalk is a mobile app; @ref: http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039  
     143         'GenericPhone'  => 'Tapatalk|PDA;|SAGEM|mmp|pocket|psp|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|wap|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser|LG-P500'  
     144     );  
     145   
     146     /** 
     147      * List of tablet devices. 
     148      * 
     149      * @var array 
     150      */  
     151     protected $tabletDevices = array(  
     152         'iPad'              => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.  
     153         'NexusTablet'       => '^.*Android.*Nexus(((?:(?!Mobile))|(?:(s(7|10).+))).)*$',  
     154         'SamsungTablet'     => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-I9205|GT-P5200|GT-P5210|SM-T311|SM-T310|SM-T210|SM-T211|SM-P900',  
     155         // @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/  
     156         'Kindle'            => 'Kindle|Silk.*Accelerated|Android.*(KFTT|KFOTE)',  
     157         // Only the Surface tablets with Windows RT are considered mobile.  
     158         // @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx  
     159         'SurfaceTablet'     => 'Windows NT [0-9.]+; ARM;',  
     160         // @note: watch out for PadFone, see #132  
     161         'AsusTablet'        => 'Transformer|TF101|^.*PadFone((?!Mobile).)*$|ME301T|ME371MG',  
     162         'BlackBerryTablet'  => 'PlayBook|RIM Tablet',  
     163         'HTCtablet'         => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',  
     164         'MotorolaTablet'    => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',  
     165         'NookTablet'        => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|LogicPD Zoom2',  
     166         // @ref: http://www.acer.ro/ac/ro/RO/content/drivers  
     167         // @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)  
     168         // @note: Can conflict with Micromax phones codes.  
     169         'AcerTablet'        => 'Android.*; (A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71)',  
     170         // @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/  
     171         // @ref: http://us.toshiba.com/tablets/tablet-finder  
     172         // @ref: http://www.toshiba.co.jp/regza/tablet/  
     173         'ToshibaTablet'     => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',  
     174         // @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html  
     175         'LGTablet'          => 'L-06C|LG-V900|LG-V909',  
     176         'FujitsuTablet'     => 'Android.*(F-01D|F-05E|F-10D|M532|Q572)',  
     177         // Prestigio Tablets http://www.prestigio.com/support  
     178         'PrestigioTablet'   => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D',  
     179         // @ref: http://support.lenovo.com/en_GB/downloads/default.page?#  
     180         'LenovoTablet'      => 'IdeaTab|S2110|S6000|K3011|A3000|A1000|A2107|A2109|A1107',  
     181         'YarvikTablet'      => 'Android.*(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468)',  
     182         'MedionTablet'      => 'Android.*OYO|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',  
     183         'ArnovaTablet'      => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',  
     184         // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/  
     185         'IRUTablet'         => 'M702pro',  
     186         'MegafonTablet'     => 'MegaFon V9|ZTE V9',  
     187         // @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/  
     188         'AllViewTablet'           => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',  
     189         // @reference: http://wiki.archosfans.com/index.php?title=Main_Page  
     190         'ArchosTablet'      => 'Android.*ARCHOS|101G9|80G9',  
     191         // @reference: http://en.wikipedia.org/wiki/NOVO7  
     192         'AinolTablet'       => 'NOVO7|Novo7Aurora|Novo7Basic|NOVO7PALADIN',  
     193         // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER  
     194         // @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser  
     195         // @ref: http://www.sony.jp/support/tablet/  
     196         'SonyTablet'        => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT211|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201',  
     197         // @ref: db + http://www.cube-tablet.com/buy-products.html  
     198         'CubeTablet'        => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',  
     199         // @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001  
     200         'CobyTablet'        => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',  
     201         // @ref: http://www.match.net.cn/products.asp  
     202         'MIDTablet'         => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733',  
     203         // @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)  
     204         // @ref: http://www.imp3.net/14/show.php?itemid=20454  
     205         'SMiTTablet'        => 'Android.*(MID|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',  
     206         // @ref: http://www.rock-chips.com/index.php?do=prod&pid=2  
     207         'RockChipTablet'    => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',  
     208         // @ref: http://www.telstra.com.au/home-phone/thub-2/  
     209         'TelstraTablet'     => 'T-Hub2',  
     210         // @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/  
     211         'FlyTablet'         => 'IQ310|Fly Vision',  
     212         // @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html  
     213         'bqTablet'          => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)',  
     214         // @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290  
     215         // @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)  
     216         'HuaweiTablet'      => 'MediaPad|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',  
     217         // Nec or Medias Tab  
     218         'NecTablet'         => 'N-06D|N-08D',  
     219         // Pantech Tablets: http://www.pantechusa.com/phones/  
     220         'PantechTablet'     => 'Pantech.*P4100',  
     221         // Broncho Tablets: http://www.broncho.cn/ (hard to find)  
     222         'BronchoTablet'     => 'Broncho.*(N701|N708|N802|a710)',  
     223         // @ref: http://versusuk.com/support.html  
     224         'VersusTablet'      => 'TOUCHPAD.*[78910]|TOUCHTAB',  
     225         // @ref: http://www.zync.in/index.php/our-products/tablet-phablets  
     226         'ZyncTablet'        => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',  
     227         // @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/  
     228         'PositivoTablet'    => 'TB07STA|TB10STA|TB07FTA|TB10FTA',  
     229         // @ref: https://www.nabitablet.com/  
     230         'NabiTablet'        => 'Android.*Nabi',  
     231         'KoboTablet'        => 'Kobo Touch|K080|Vox Build|Arc Build',  
     232         // French Danew Tablets http://www.danew.com/produits-tablette.php  
     233         'DanewTablet'       => 'DSlide.*(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)',  
     234         // Texet Tablets and Readers http://www.texet.ru/tablet/  
     235         'TexetTablet'       => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',  
     236         // @note: Avoid detecting 'PLAYSTATION 3' as mobile.  
     237         'PlaystationTablet' => 'Playstation.*(Portable|Vita)',  
     238         // @ref: http://www.galapad.net/product.html  
     239         'GalapadTablet'     => 'Android.*G1',  
     240         // @ref: http://www.micromaxinfo.com/tablet/funbook  
     241         'MicromaxTablet'    => 'Funbook|Micromax.*(P250|P560|P360|P362|P600|P300|P350|P500|P275)',  
     242         // http://www.karbonnmobiles.com/products_tablet.php  
     243         'KarbonnTablet'     => 'Android.*(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)',  
     244         // @ref: http://www.gloryunion.cn/products.asp  
     245         // @ref: http://www.allwinnertech.com/en/apply/mobile.html  
     246         // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.  
     247         'GUTablet'          => 'TX-A1301|TX-M9002|Q702', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G  
     248         'GenericTablet'     => 'Android.*97D|Tablet(?!.*PC)|ViewPad7|BNTV250A|MID-WCDMA|LogicPD Zoom2|A7EB|CatNova8|A1_07|CT704|CT1002|M721|hp-tablet|rk30sdk',  
     249     );  
     250   
     251     /** 
     252      * List of mobile Operating Systems. 
     253      * 
     254      * @var array 
     255      */  
     256     protected $operatingSystems = array(  
     257         'AndroidOS'         => 'Android',  
     258         'BlackBerryOS'      => 'blackberry|BB10|rim tablet os',  
     259         'PalmOS'            => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',  
     260         'SymbianOS'         => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|S60',  
     261         // @reference: http://en.wikipedia.org/wiki/Windows_Mobile  
     262         'WindowsMobileOS'   => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',  
     263         // @reference: http://en.wikipedia.org/wiki/Windows_Phone  
     264         // http://wifeng.cn/?r=blog&a=view&id=106  
     265         // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx  
     266         'WindowsPhoneOS'   => 'Windows Phone OS|XBLWP7|ZuneWP7',  
     267         'iOS'               => 'iPhone.*Mobile|iPod|iPad',  
     268         // http://en.wikipedia.org/wiki/MeeGo  
     269         // @todo: research MeeGo in UAs  
     270         'MeeGoOS'           => 'MeeGo',  
     271         // http://en.wikipedia.org/wiki/Maemo  
     272         // @todo: research Maemo in UAs  
     273         'MaemoOS'           => 'Maemo',  
     274         'JavaOS'            => 'J2ME/|MIDP|CLDC', // '|Java/' produces bug #135  
     275         'webOS'             => 'webOS|hpwOS',  
     276         'badaOS'            => 'Bada',  
     277         'BREWOS'            => 'BREW',  
     278     );  
     279   
     280     /** 
     281      * List of mobile User Agents. 
     282      * 
     283      * @var array 
     284      */  
     285     protected $userAgents = array(  
     286         // @reference: https://developers.google.com/chrome/mobile/docs/user-agent  
     287         'Chrome'          => 'CrMo|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',  
     288         'Dolfin'          => 'Dolfin',  
     289         'Opera'           => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+',  
     290         'Skyfire'         => 'Skyfire',  
     291         'IE'              => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+  
     292         'Firefox'         => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',  
     293         'Bolt'            => 'bolt',  
     294         'TeaShark'        => 'teashark',  
     295         'Blazer'          => 'Blazer',  
     296         // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3  
     297         'Safari'          => 'Version.*Mobile.*Safari|Safari.*Mobile',  
     298         // @ref: http://en.wikipedia.org/wiki/Midori_(web_browser)  
     299         //'Midori'          => 'midori',  
     300         'Tizen'           => 'Tizen',  
     301         'UCBrowser'       => 'UC.*Browser|UCWEB',  
     302         // @ref: https://github.com/serbanghita/Mobile-Detect/issues/7  
     303         'DiigoBrowser'    => 'DiigoBrowser',  
     304         // http://www.puffinbrowser.com/index.php  
     305         'Puffin'            => 'Puffin',  
     306         // @ref: http://mercury-browser.com/index.html  
     307         'Mercury'          => 'Mercury',  
     308         // @reference: http://en.wikipedia.org/wiki/Minimo  
     309         // http://en.wikipedia.org/wiki/Vision_Mobile_Browser  
     310         'GenericBrowser'  => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision'  
     311     );  
     312   
     313     /** 
     314      * Utilities. 
     315      * 
     316      * @var array 
     317      */  
     318     protected $utilities = array(  
     319         // Experimental. When a mobile device wants to switch to 'Desktop Mode'.  
     320         // @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/  
     321         // @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011  
     322         'DesktopMode' => 'WPDesktop',  
     323         'TV'          => 'SonyDTV|HbbTV', // experimental  
     324         'WebKit'      => '(webkit)[ /]([w.]+)',  
     325         'Bot'         => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',  
     326         'MobileBot'   => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',  
     327         'Watch'       => 'SM-V700',  
     328     );  
     329   
     330     /** 
     331      * The individual segments that could exist in a User-Agent string. VER refers to the regular 
     332      * expression defined in the constant self::VER. 
     333      * 
     334      * @var array 
     335      */  
     336     protected $properties = array(  
     337   
     338         // Build  
     339         'Mobile'        => 'Mobile/[VER]',  
     340         'Build'         => 'Build/[VER]',  
     341         'Version'       => 'Version/[VER]',  
     342         'VendorID'      => 'VendorID/[VER]',  
     343   
     344         // Devices  
     345         'iPad'          => 'iPad.*CPU[a-z ]+[VER]',  
     346         'iPhone'        => 'iPhone.*CPU[a-z ]+[VER]',  
     347         'iPod'          => 'iPod.*CPU[a-z ]+[VER]',  
     348         //'BlackBerry'    => array('BlackBerry[VER]', 'BlackBerry [VER];'),  
     349         'Kindle'        => 'Kindle/[VER]',  
     350   
     351         // Browser  
     352         'Chrome'        => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),  
     353         'Dolfin'        => 'Dolfin/[VER]',  
     354         // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference  
     355         'Firefox'       => 'Firefox/[VER]',  
     356         'Fennec'        => 'Fennec/[VER]',  
     357         // @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx  
     358         'IE'      => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'),  
     359         // http://en.wikipedia.org/wiki/NetFront  
     360         'NetFront'      => 'NetFront/[VER]',  
     361         'NokiaBrowser'  => 'NokiaBrowser/[VER]',  
     362         'Opera'         => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),  
     363         'Opera Mini'    => 'Opera Mini/[VER]',  
     364         'Opera Mobi'    => 'Version/[VER]',  
     365         'UC Browser'    => 'UC Browser[VER]',  
     366         // @note: Safari 7534.48.3 is actually Version 5.1.  
     367         // @note: On BlackBerry the Version is overwriten by the OS.  
     368         'Safari'        => array( 'Version/[VER]', 'Safari/[VER]' ),  
     369         'Skyfire'       => 'Skyfire/[VER]',  
     370         'Tizen'         => 'Tizen/[VER]',  
     371         'Webkit'        => 'webkit[ /][VER]',  
     372   
     373         // Engine  
     374         'Gecko'         => 'Gecko/[VER]',  
     375         'Trident'       => 'Trident/[VER]',  
     376         'Presto'        => 'Presto/[VER]',  
     377   
     378         // OS  
     379         'iOS'              => ' OS [VER] ',  
     380         'Android'          => 'Android [VER]',  
     381         'BlackBerry'       => array('BlackBerry[w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),  
     382         'BREW'             => 'BREW [VER]',  
     383         'Java'             => 'Java/[VER]',  
     384         // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx  
     385         // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases  
     386         'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),  
     387         'Windows Phone'    => 'Windows Phone [VER]',  
     388         'Windows CE'       => 'Windows CE/[VER]',  
     389         // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd  
     390         'Windows NT'       => 'Windows NT [VER]',  
     391         'Symbian'          => array('SymbianOS/[VER]', 'Symbian/[VER]'),  
     392         'webOS'            => array('webOS/[VER]', 'hpwOS/[VER];'),  
     393     );  
     394   
     395     /** 
     396      * Construct an instance of this class. 
     397      * 
     398      * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored. 
     399      *                       If left empty, will use the global _SERVER['HTTP_*'] vars instead. 
     400      * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT 
     401      *                          from the $headers array instead. 
     402      */  
     403     public function __construct(  
     404         array $headers = null,  
     405         $userAgent = null  
     406     ){  
     407         $this->setHttpHeaders($headers);  
     408         $this->setUserAgent($userAgent);  
     409   
     410         $this->setMobileDetectionRules();  
     411         $this->setMobileDetectionRulesExtended();  
     412     }  
     413   
     414     /** 
     415     * Get the current script version. 
     416     * This is useful for the demo.php file, 
     417     * so people can check on what version they are testing 
     418     * for mobile devices. 
     419     * 
     420     * @return string The version number in "X.Y.Z" format. 
     421     */  
     422     public function getScriptVersion()  
     423     {  
     424         return $this->scriptVersion;  
     425     }  
     426   
     427     /** 
     428      * Set the HTTP Headers. Must be PHP-flavored. 
     429      * 
     430      * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract 
     431      *                           the headers. The default null is left for backwards compatibilty. 
     432      */  
     433     public function setHttpHeaders($httpHeaders = null)  
     434     {  
     435         //use global _SERVER if $httpHeaders aren't defined  
     436         if (!is_array($httpHeaders) || !count($httpHeaders)) {  
     437             $httpHeaders = $_SERVER;  
     438         }  
     439   
     440         //Only save HTTP headers. In PHP land, that means only _SERVER vars that  
     441         //start with HTTP_.  
     442         foreach ($httpHeaders as $key => $value) {  
     443             if (substr($key,0,5) == 'HTTP_') {  
     444                 $this->httpHeaders[$key] = $value;  
     445             }  
     446         }  
     447     }  
     448   
     449     /** 
     450      * Retrieves the HTTP headers. 
     451      * 
     452      * @return array 
     453      */  
     454     public function getHttpHeaders()  
     455     {  
     456         return $this->httpHeaders;  
     457     }  
     458   
     459     /** 
     460      * Retrieves a particular header. If it doesn't exist, no exception/error is caused. 
     461      * Simply null is returned. 
     462      * 
     463      * @param string $header The name of the header to retrieve. Can be HTTP compliant such as 
     464      *                       "User-Agent" or "X-Device-User-Agent" or can be php-esque with the 
     465      *                       all-caps, HTTP_ prefixed, underscore seperated awesomeness. 
     466      * 
     467      * @return string|null The value of the header. 
     468      */  
     469     public function getHttpHeader($header)  
     470     {  
     471         //are we using PHP-flavored headers?  
     472         if (strpos($header, '_') === false) {  
     473             $header = str_replace('-', '_', $header);  
     474             $header = strtoupper($header);  
     475         }  
     476   
     477         //test the alternate, too  
     478         $altHeader = 'HTTP_' . $header;  
     479   
     480         //Test both the regular and the HTTP_ prefix  
     481         if (isset($this->httpHeaders[$header])) {  
     482             return $this->httpHeaders[$header];  
     483         } elseif (isset($this->httpHeaders[$altHeader])) {  
     484             return $this->httpHeaders[$altHeader];  
     485         }  
     486     }  
     487   
     488     /** 
     489      * Set the User-Agent to be used. 
     490      * 
     491      * @param string $userAgent The user agent string to set. 
     492      */  
     493     public function setUserAgent($userAgent = null)  
     494     {  
     495         if (!empty($userAgent)) {  
     496             $this->userAgent = $userAgent;  
     497         } else {  
     498             $this->userAgent = $this->getHttpHeader('User-Agent');  
     499   
     500             if (empty($this->userAgent)) {  
     501                 $this->userAgent = $this->getHttpHeader('X-Device-User-Agent');  
     502             }  
     503   
     504             //Header can occur on devices using Opera Mini (can expose the real device type).  
     505             //Let's concatenate it (we need this extra info in the regexes).  
     506             if ($operaMiniUa = $this->getHttpHeader('X-OperaMini-Phone-UA')) {  
     507                 $this->userAgent .= ' ' . $operaMiniUa;  
     508             }  
     509         }  
     510     }  
     511   
     512     /** 
     513      * Retrieve the User-Agent. 
     514      * 
     515      * @return string|null The user agent if it's set. 
     516      */  
     517     public function getUserAgent()  
     518     {  
     519         return $this->userAgent;  
     520     }  
     521   
     522     /** 
     523      * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or 
     524      * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set. 
     525      * 
     526      * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default 
     527      *                     parameter is null which will default to self::DETECTION_TYPE_MOBILE. 
     528      */  
     529     public function setDetectionType($type = null)  
     530     {  
     531         if ($type === null) {  
     532             $type = self::DETECTION_TYPE_MOBILE;  
     533         }  
     534   
     535         if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) {  
     536             return;  
     537         }  
     538   
     539         $this->detectionType = $type;  
     540     }  
     541   
     542     /** 
     543      * Retrieve the list of known phone devices. 
     544      * 
     545      * @return array List of phone devices. 
     546      */  
     547     public function getPhoneDevices()  
     548     {  
     549         return $this->phoneDevices;  
     550     }  
     551   
     552     /** 
     553      * Retrieve the list of known tablet devices. 
     554      * 
     555      * @return array List of tablet devices. 
     556      */  
     557     public function getTabletDevices()  
     558     {  
     559         return $this->tabletDevices;  
     560     }  
     561   
     562     /** 
     563      * Method sets the mobile detection rules. This method is used for the magic methods $detect->is*(). 
     564      */  
     565     public function setMobileDetectionRules()  
     566     {  
     567         // Merge all rules together.  
     568         $this->mobileDetectionRules = array_merge(  
     569             $this->phoneDevices,  
     570             $this->tabletDevices,  
     571             $this->operatingSystems,  
     572             $this->userAgents  
     573         );  
     574   
     575     }  
     576   
     577     /** 
     578      * Method sets the mobile detection rules + utilities. 
     579      * The reason this is separate is because utilities rules 
     580      * don't necessary imply mobile. This method is used inside 
     581      * the new $detect->is('stuff') method. 
     582      */  
     583     public function setMobileDetectionRulesExtended()  
     584     {  
     585         // Merge all rules together.  
     586         $this->mobileDetectionRulesExtended = array_merge(  
     587             $this->phoneDevices,  
     588             $this->tabletDevices,  
     589             $this->operatingSystems,  
     590             $this->userAgents,  
     591             $this->utilities  
     592         );  
     593   
     594     }  
     595   
     596     /** 
     597      * Retrieve the current set of rules. 
     598      * 
     599      * @return array 
     600      */  
     601     public function getRules()  
     602     {  
     603         if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) {  
     604             return $this->mobileDetectionRulesExtended;  
     605         } else {  
     606             return $this->mobileDetectionRules;  
     607         }  
     608     }  
     609   
     610     /** 
     611     * Check the HTTP headers for signs of mobile. 
     612     * This is the fastest mobile check possible; it's used 
     613     * inside isMobile() method. 
     614     * 
     615     * @return bool 
     616     */  
     617     public function checkHttpHeadersForMobile()  
     618     {  
     619         return(  
     620             isset($this->httpHeaders['HTTP_ACCEPT']) &&  
     621                 (strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/x-obml2d') !== false || // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/  
     622                  strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.rim.html') !== false || // BlackBerry devices.  
     623                  strpos($this->httpHeaders['HTTP_ACCEPT'], 'text/vnd.wap.wml') !== false ||  
     624                  strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.wap.xhtml+xml') !== false) ||  
     625             isset($this->httpHeaders['HTTP_X_WAP_PROFILE'])             || // @todo: validate  
     626             isset($this->httpHeaders['HTTP_X_WAP_CLIENTID'])            ||  
     627             isset($this->httpHeaders['HTTP_WAP_CONNECTION'])            ||  
     628             isset($this->httpHeaders['HTTP_PROFILE'])                   ||  
     629             isset($this->httpHeaders['HTTP_X_OPERAMINI_PHONE_UA'])      || // Reported by Nokia devices (eg. C3)  
     630             isset($this->httpHeaders['HTTP_X_NOKIA_IPADDRESS'])         ||  
     631             isset($this->httpHeaders['HTTP_X_NOKIA_GATEWAY_ID'])        ||  
     632             isset($this->httpHeaders['HTTP_X_ORANGE_ID'])               ||  
     633             isset($this->httpHeaders['HTTP_X_VODAFONE_3GPDPCONTEXT'])   ||  
     634             isset($this->httpHeaders['HTTP_X_HUAWEI_USERID'])           ||  
     635             isset($this->httpHeaders['HTTP_UA_OS'])                     || // Reported by Windows Smartphones.  
     636             isset($this->httpHeaders['HTTP_X_MOBILE_GATEWAY'])          || // Reported by Verizon, Vodafone proxy system.  
     637             isset($this->httpHeaders['HTTP_X_ATT_DEVICEID'])            || // Seen this on HTC Sensation. @ref: SensationXE_Beats_Z715e  
     638             //HTTP_X_NETWORK_TYPE = WIFI  
     639             ( isset($this->httpHeaders['HTTP_UA_CPU']) &&  
     640                     $this->httpHeaders['HTTP_UA_CPU'] == 'ARM'          // Seen this on a HTC.  
     641             )  
     642         );  
     643     }  
     644   
     645     /** 
     646      * Magic overloading method. 
     647      * 
     648      * @method boolean is[...]() 
     649      * @param  string                 $name 
     650      * @param  array                  $arguments 
     651      * @return mixed 
     652      * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' 
     653      */  
     654     public function __call($name, $arguments)  
     655     {  
     656         //make sure the name starts with 'is', otherwise  
     657         if (substr($name, 0, 2) != 'is') {  
     658             throw new BadMethodCallException("No such method exists: $name");  
     659         }  
     660   
     661         $this->setDetectionType(self::DETECTION_TYPE_MOBILE);  
     662   
     663         $key = substr($name, 2);  
     664   
     665         return $this->matchUAAgainstKey($key);  
     666     }  
     667   
     668     /** 
     669     * Find a detection rule that matches the current User-agent. 
     670     * 
     671     * @param null $userAgent deprecated 
     672     * @return boolean 
     673     */  
     674     private function matchDetectionRulesAgainstUA($userAgent = null)  
     675     {  
     676         // Begin general search.  
     677         foreach ($this->getRules() as $_regex) {  
     678             if (empty($_regex)) {  
     679                 continue;  
     680             }  
     681             if ($this->match($_regex, $userAgent)) {  
     682                 return true;  
     683             }  
     684         }  
     685   
     686         return false;  
     687     }  
     688   
     689     /** 
     690     * Search for a certain key in the rules array. 
     691     * If the key is found the try to match the corresponding 
     692     * regex agains the User-Agent. 
     693     * 
     694     * @param string $key 
     695     * @param null $userAgent deprecated 
     696     * @return mixed 
     697     */  
     698     private function matchUAAgainstKey($key, $userAgent = null)  
     699     {  
     700         // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.  
     701         $key = strtolower($key);  
     702   
     703         //change the keys to lower case  
     704         $_rules = array_change_key_case($this->getRules());  
     705   
     706         if (array_key_exists($key, $_rules)) {  
     707             if (empty($_rules[$key])) {  
     708                 return null;  
     709             }  
     710   
     711             return $this->match($_rules[$key], $userAgent);  
     712         }  
     713   
     714         return false;  
     715     }  
     716   
     717     /** 
     718     * Check if the device is mobile. 
     719     * Returns true if any type of mobile device detected, including special ones 
     720     * @param null $userAgent deprecated 
     721     * @param null $httpHeaders deprecated 
     722     * @return bool 
     723     */  
     724     public function isMobile($userAgent = null, $httpHeaders = null)  
     725     {  
     726   
     727         if ($httpHeaders) {  
     728             $this->setHttpHeaders($httpHeaders);  
     729         }  
     730   
     731         if ($userAgent) {  
     732             $this->setUserAgent($userAgent);  
     733         }  
     734   
     735         $this->setDetectionType(self::DETECTION_TYPE_MOBILE);  
     736   
     737         if ($this->checkHttpHeadersForMobile()) {  
     738             return true;  
     739         } else {  
     740             return $this->matchDetectionRulesAgainstUA();  
     741         }  
     742   
     743     }  
     744   
     745     /** 
     746      * Check if the device is a tablet. 
     747      * Return true if any type of tablet device is detected. 
     748      * 
     749      * @param  string $userAgent   deprecated 
     750      * @param  array  $httpHeaders deprecated 
     751      * @return bool 
     752      */  
     753     public function isTablet($userAgent = null, $httpHeaders = null)  
     754     {  
     755         $this->setDetectionType(self::DETECTION_TYPE_MOBILE);  
     756   
     757         foreach ($this->tabletDevices as $_regex) {  
     758             if ($this->match($_regex, $userAgent)) {  
     759                 return true;  
     760             }  
     761         }  
     762   
     763         return false;  
     764     }  
     765   
     766     /** 
     767      * This method checks for a certain property in the 
     768      * userAgent. 
     769      * @todo: The httpHeaders part is not yet used. 
     770      * 
     771      * @param $key 
     772      * @param  string        $userAgent   deprecated 
     773      * @param  string        $httpHeaders deprecated 
     774      * @return bool|int|null 
     775      */  
     776     public function is($key, $userAgent = null, $httpHeaders = null)  
     777     {  
     778         // Set the UA and HTTP headers only if needed (eg. batch mode).  
     779         if ($httpHeaders) {  
     780             $this->setHttpHeaders($httpHeaders);  
     781         }  
     782   
     783         if ($userAgent) {  
     784             $this->setUserAgent($userAgent);  
     785         }  
     786   
     787         $this->setDetectionType(self::DETECTION_TYPE_EXTENDED);  
     788   
     789         return $this->matchUAAgainstKey($key);  
     790     }  
     791   
     792     /** 
     793      * Retrieve the list of mobile operating systems. 
     794      * 
     795      * @return array The list of mobile operating systems. 
     796      */  
     797     public function getOperatingSystems()  
     798     {  
     799         return $this->operatingSystems;  
     800     }  
     801   
     802     /** 
     803      * Some detection rules are relative (not standard), 
     804      * because of the diversity of devices, vendors and 
     805      * their conventions in representing the User-Agent or 
     806      * the HTTP headers. 
     807      * 
     808      * This method will be used to check custom regexes against 
     809      * the User-Agent string. 
     810      * 
     811      * @param $regex 
     812      * @param  string $userAgent 
     813      * @return bool 
     814      * 
     815      * @todo: search in the HTTP headers too. 
     816      */  
     817     public function match($regex, $userAgent = null)  
     818     {  
     819         // Escape the special character which is the delimiter.  
     820         $regex = str_replace('/', '/', $regex);  
     821   
     822         return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent));  
     823     }  
     824   
     825     /** 
     826      * Get the properties array. 
     827      * 
     828      * @return array 
     829      */  
     830     public function getProperties()  
     831     {  
     832         return $this->properties;  
     833     }  
     834   
     835     /** 
     836      * Prepare the version number. 
     837      * 
     838      * @todo Remove the error supression from str_replace() call. 
     839      * 
     840      * @param string $ver The string version, like "2.6.21.2152"; 
     841      * 
     842      * @return float 
     843      */  
     844     public function prepareVersionNo($ver)  
     845     {  
     846         $ver = str_replace(array('_', ' ', '/'), array('.', '.', '.'), $ver);  
     847         $arrVer = explode('.', $ver, 2);  
     848   
     849         if (isset($arrVer[1])) {  
     850             $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.  
     851         }  
     852   
     853         return (float) implode('.', $arrVer);  
     854     }  
     855   
     856     /** 
     857      * Check the version of the given property in the User-Agent. 
     858      * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) 
     859      * 
     860      * @param  string $propertyName 
     861      * @param  string $type 
     862      * @return mixed  $version 
     863      */  
     864     public function version($propertyName, $type = 'text')  
     865     {  
     866         if (empty($propertyName)) {  
     867             return false;  
     868         }  
     869   
     870         if (!in_array($type, array('text', 'float'))) {  
     871             $type = 'text';  
     872         }  
     873   
     874         $properties = $this->getProperties();  
     875   
     876         // Check if the property exists in the properties array.  
     877         if (array_key_exists($propertyName, $properties)) {  
     878   
     879             // Prepare the pattern to be matched.  
     880             // Make sure we always deal with an array (string is converted).  
     881             $properties[$propertyName] = (array) $properties[$propertyName];  
     882   
     883             foreach ($properties[$propertyName] as $propertyMatchString) {  
     884   
     885                 $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);  
     886   
     887                 // Escape the special character which is the delimiter.  
     888                 $propertyPattern = str_replace('/', '/', $propertyPattern);  
     889   
     890                 // Identify and extract the version.  
     891                 preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match);  
     892   
     893                 if (!empty($match[1])) {  
     894                     $version = ( $type == 'float' ? $this->prepareVersionNo($match[1]) : $match[1] );  
     895   
     896                     return $version;  
     897                 }  
     898   
     899             }  
     900   
     901         }  
     902   
     903         return false;  
     904     }  
     905   
     906     /** 
     907      * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants. 
     908      * 
     909      * @return string One of the self::MOBILE_GRADE_* constants. 
     910      */  
     911     public function mobileGrade()  
     912     {  
     913         $isMobile = $this->isMobile();  
     914   
     915         if (  
     916             // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)  
     917             $this->version('iPad', 'float')>=4.3 ||  
     918             $this->version('iPhone', 'float')>=3.1 ||  
     919             $this->version('iPod', 'float')>=3.1 ||  
     920   
     921             // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)  
     922             // Android 3.1 (Honeycomb)  - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM  
     923             // Android 4.0 (ICS)  - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices  
     924             // Android 4.1 (Jelly Bean)  - Tested on a Galaxy Nexus and Galaxy 7  
     925             ( $this->version('Android', 'float')>2.1 && $this->is('Webkit') ) ||  
     926   
     927             // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800  
     928             $this->version('Windows Phone OS', 'float')>=7.0 ||  
     929   
     930             // Blackberry 7 - Tested on BlackBerry® Torch 9810  
     931             // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670  
     932             $this->is('BlackBerry') && $this->version('BlackBerry', 'float')>=6.0 ||  
     933             // Blackberry Playbook (1.0-2.0) - Tested on PlayBook  
     934             $this->match('Playbook.*Tablet') ||  
     935   
     936             // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)  
     937             ( $this->version('webOS', 'float')>=1.4 && $this->match('Palm|Pre|Pixi') ) ||  
     938             // Palm WebOS 3.0  - Tested on HP TouchPad  
     939             $this->match('hp.*TouchPad') ||  
     940   
     941             // Firefox Mobile (12 Beta) - Tested on Android 2.3 device  
     942             ( $this->is('Firefox') && $this->version('Firefox', 'float')>=12 ) ||  
     943   
     944             // Chrome for Android - Tested on Android 4.0, 4.1 device  
     945             ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', 'float')>=4.0 ) ||  
     946   
     947             // Skyfire 4.1 - Tested on Android 2.3 device  
     948             ( $this->is('Skyfire') && $this->version('Skyfire', 'float')>=4.1 && $this->is('AndroidOS') && $this->version('Android', 'float')>=2.3 ) ||  
     949   
     950             // Opera Mobile 11.5-12: Tested on Android 2.3  
     951             ( $this->is('Opera') && $this->version('Opera Mobi', 'float')>11 && $this->is('AndroidOS') ) ||  
     952   
     953             // Meego 1.2 - Tested on Nokia 950 and N9  
     954             $this->is('MeeGoOS') ||  
     955   
     956             // Tizen (pre-release) - Tested on early hardware  
     957             $this->is('Tizen') ||  
     958   
     959             // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser  
     960             // @todo: more tests here!  
     961             $this->is('Dolfin') && $this->version('Bada', 'float')>=2.0 ||  
     962   
     963             // UC Browser - Tested on Android 2.3 device  
     964             ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', 'float')>=2.3 ) ||  
     965   
     966             // Kindle 3 and Fire  - Tested on the built-in WebKit browser for each  
     967             ( $this->match('Kindle Fire') ||  
     968             $this->is('Kindle') && $this->version('Kindle', 'float')>=3.0 ) ||  
     969   
     970             // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet  
     971             $this->is('AndroidOS') && $this->is('NookTablet') ||  
     972   
     973             // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7  
     974             $this->version('Chrome', 'float')>=11 && !$isMobile ||  
     975   
     976             // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7  
     977             $this->version('Safari', 'float')>=5.0 && !$isMobile ||  
     978   
     979             // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7  
     980             $this->version('Firefox', 'float')>=4.0 && !$isMobile ||  
     981   
     982             // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7  
     983             $this->version('MSIE', 'float')>=7.0 && !$isMobile ||  
     984   
     985             // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7  
     986             // @reference: http://my.opera.com/community/openweb/idopera/  
     987             $this->version('Opera', 'float')>=10 && !$isMobile  
     988   
     989   
     990         ){  
     991             return self::MOBILE_GRADE_A;  
     992         }  
     993   
     994         if (  
     995             $this->version('iPad', 'float')<4.3 ||  
     996             $this->version('iPhone', 'float')<3.1 ||  
     997             $this->version('iPod', 'float')<3.1 ||  
     998   
     999             // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770  
    1000             $this->is('Blackberry') && $this->version('BlackBerry', 'float')>=5 && $this->version('BlackBerry', 'float')<6 ||  
    1001   
    1002             //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3  
    1003             ( $this->version('Opera Mini', 'float')>=5.0 && $this->version('Opera Mini', 'float')<=6.5 &&  
    1004             ($this->version('Android', 'float')>=2.3 || $this->is('iOS')) ) ||  
    1005   
    1006             // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)  
    1007             $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||  
    1008   
    1009             // @todo: report this (tested on Nokia N71)  
    1010             $this->version('Opera Mobi', 'float')>=11 && $this->is('SymbianOS')  
    1011         ){  
    1012             return self::MOBILE_GRADE_B;  
    1013         }  
    1014   
    1015         if (  
    1016             // Blackberry 4.x - Tested on the Curve 8330  
    1017             $this->version('BlackBerry', 'float')<5.0 ||  
    1018             // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)  
    1019             $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', 'float')<=5.2  
    1020   
    1021   
    1022         ){  
    1023             return self::MOBILE_GRADE_C;  
    1024         }  
    1025   
    1026         //All older smartphone platforms and featurephones - Any device that doesn't support media queries  
    1027         //will receive the basic, C grade experience.  
    1028         return self::MOBILE_GRADE_C;  
    1029     }  
    1030 }  
    1031 
    1032 简单的使用方法如下:
    1033 [php] view plaincopy 
    1034 //使用实例  
    1035    
    1036 include 'Mobile_Detect.php';  
    1037 $detect = new Mobile_Detect();  
    1038    
    1039 // Check for any mobile device.  
    1040 if ($detect->isMobile())  
    1041    
    1042 // Check for any tablet.  
    1043 if($detect->isTablet())  
    1044    
    1045 // Check for any mobile device, excluding tablets.  
    1046 if ($detect->isMobile() && !$detect->isTablet())  
    1047    
    1048 if ($detect->isMobile() && !$detect->isTablet())  
    1049    
    1050 // Alternative to $detect->isAndroidOS()  
    1051 $detect->is('AndroidOS');  
    1052    
    1053 // Batch usage  
    1054 foreach($userAgents as $userAgent){  
    1055   $detect->setUserAgent($userAgent);  
    1056   $isMobile = $detect->isMobile();  
    1057 }  
    1058    
    1059 // Version check.  
    1060 $detect->version('iPad'); // 4.3 (float)  
  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/code81/p/4953035.html
Copyright © 2011-2022 走看看