: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
// http://en.wikipedia.org/wiki/Maemo
// @todo: research Maemo in UAs
'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
'webOS' => 'webOS|hpwOS',
* List of mobile User Agents.
* IMPORTANT: This is a list of only mobile browsers.
* Mobile Detect 2.x supports only mobile browsers,
* it was never designed to detect all browsers.
* The change will come in 2017 in the 3.x release for PHP7.
protected static $browsers = array(
//'Vivaldi' => 'Vivaldi',
// @reference: https://developers.google.com/chrome/mobile/docs/user-agent
'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
'Dolfin' => '\bDolfin\b',
'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+$|Coast/[0-9.]+',
'Edge' => 'Mobile Safari/[.0-9]* Edge',
'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+
'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS',
'TeaShark' => 'teashark',
// @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari',
// http://en.wikipedia.org/wiki/Midori_(web_browser)
'WeChat' => '\bMicroMessenger\b',
'UCBrowser' => 'UC.*Browser|UCWEB',
'baiduboxapp' => 'baiduboxapp',
'baidubrowser' => 'baidubrowser',
// https://github.com/serbanghita/Mobile-Detect/issues/7
'DiigoBrowser' => 'DiigoBrowser',
// http://www.puffinbrowser.com/index.php
// http://mercury-browser.com/index.html
'Mercury' => '\bMercury\b',
// http://en.wikipedia.org/wiki/Obigo_Browser
'ObigoBrowser' => 'Obigo',
// http://en.wikipedia.org/wiki/NetFront
'NetFront' => 'NF-Browser',
// @reference: http://en.wikipedia.org/wiki/Minimo
// http://en.wikipedia.org/wiki/Vision_Mobile_Browser
'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger',
// @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser)
'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon',
protected static $utilities = array(
// Experimental. When a mobile device wants to switch to 'Desktop Mode'.
// http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
// https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
// https://developers.facebook.com/docs/sharing/best-practices
'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom',
'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2',
'DesktopMode' => 'WPDesktop',
'TV' => 'SonyDTV|HbbTV', // experimental
'WebKit' => '(webkit)[ /]([\w.]+)',
// @todo: Include JXD consoles.
'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\b',
* All possible HTTP headers that represent the
protected static $uaHttpHeaders = array(
// The default User-Agent string.
// Header can occur on devices using Opera Mini.
'HTTP_X_OPERAMINI_PHONE_UA',
// Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
'HTTP_X_DEVICE_USER_AGENT',
'HTTP_X_ORIGINAL_USER_AGENT',
'HTTP_X_UCBROWSER_DEVICE_UA'
* The individual segments that could exist in a User-Agent string. VER refers to the regular
* expression defined in the constant self::VER.
protected static $properties = array(
'Mobile' => 'Mobile/[VER]',
'Build' => 'Build/[VER]',
'Version' => 'Version/[VER]',
'VendorID' => 'VendorID/[VER]',
'iPad' => 'iPad.*CPU[a-z ]+[VER]',
'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
'iPod' => 'iPod.*CPU[a-z ]+[VER]',
//'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
'Kindle' => 'Kindle/[VER]',
'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
'Coast' => array('Coast/[VER]'),
'Dolfin' => 'Dolfin/[VER]',
// @reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox
'Firefox' => array('Firefox/[VER]', 'FxiOS/[VER]'),
'Fennec' => 'Fennec/[VER]',
// http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]'),
// http://en.wikipedia.org/wiki/NetFront
'NetFront' => 'NetFront/[VER]',
'NokiaBrowser' => 'NokiaBrowser/[VER]',
'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
'Opera Mini' => 'Opera Mini/[VER]',
'Opera Mobi' => 'Version/[VER]',
'UCBrowser' => array( 'UCWEB[VER]', 'UC.*Browser/[VER]' ),
'MQQBrowser' => 'MQQBrowser/[VER]',
'MicroMessenger' => 'MicroMessenger/[VER]',
'baiduboxapp' => 'baiduboxapp/[VER]',
'baidubrowser' => 'baidubrowser/[VER]',
'SamsungBrowser' => 'SamsungBrowser/[VER]',
// @note: Safari 7534.48.3 is actually Version 5.1.
// @note: On BlackBerry the Version is overwriten by the OS.
'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
'Skyfire' => 'Skyfire/[VER]',
'Tizen' => 'Tizen/[VER]',
'Webkit' => 'webkit[ /][VER]',
'PaleMoon' => 'PaleMoon/[VER]',
'Gecko' => 'Gecko/[VER]',
'Trident' => 'Trident/[VER]',
'Presto' => 'Presto/[VER]',
'Goanna' => 'Goanna/[VER]',
'iOS' => ' \bi?OS\b [VER][ ;]{1}',
'Android' => 'Android [VER]',
'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
// @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
// @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
'Windows Phone' => 'Windows Phone [VER]',
'Windows CE' => 'Windows CE/[VER]',
// http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
'Windows NT' => 'Windows NT [VER]',
'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
* Construct an instance of this class.
* @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
* If left empty, will use the global _SERVER['HTTP_*'] vars instead.
* @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
* from the $headers array instead.
public function __construct(
$this->setHttpHeaders($headers);
$this->setUserAgent($userAgent);
* Get the current script version.
* This is useful for the demo.php file,
* so people can check on what version they are testing
* @return string The version number in semantic version format.
public static function getScriptVersion()
* Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
* @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
* the headers. The default null is left for backwards compatibility.
public function setHttpHeaders($httpHeaders = null)
// use global _SERVER if $httpHeaders aren't defined
if (!is_array($httpHeaders) || !count($httpHeaders)) {
// clear existing headers
$this->httpHeaders = array();
// Only save HTTP headers. In PHP land, that means only _SERVER vars that
foreach ($httpHeaders as $key => $value) {
if (substr($key, 0, 5) === 'HTTP_') {
$this->httpHeaders[$key] = $value;
// In case we're dealing with CloudFront, we need to know.
$this->setCfHeaders($httpHeaders);
* Retrieves the HTTP headers.
public function getHttpHeaders()
return $this->httpHeaders;
* Retrieves a particular header. If it doesn't exist, no exception/error is caused.
* Simply null is returned.
* @param string $header The name of the header to retrieve. Can be HTTP compliant such as
* "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
* all-caps, HTTP_ prefixed, underscore seperated awesomeness.
* @return string|null The value of the header.
public function getHttpHeader($header)
// are we using PHP-flavored headers?
if (strpos($header, '_') === false) {
$header = str_replace('-', '_', $header);
$header = strtoupper($header);
// test the alternate, too
$altHeader = 'HTTP_' . $header;
//Test both the regular and the HTTP_ prefix
if (isset($this->httpHeaders[$header])) {
return $this->httpHeaders[$header];
} elseif (isset($this->httpHeaders[$altHeader])) {
return $this->httpHeaders[$altHeader];
public function getMobileHeaders()
return self::$mobileHeaders;
* Get all possible HTTP headers that
* can contain the User-Agent string.
* @return array List of HTTP headers.
public function getUaHttpHeaders()
return self::$uaHttpHeaders;
* http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device
* @param array $cfHeaders List of HTTP headers
* @return boolean If there were CloudFront headers to be set
public function setCfHeaders($cfHeaders = null) {
// use global _SERVER if $cfHeaders aren't defined
if (!is_array($cfHeaders) || !count($cfHeaders)) {
// clear existing headers
$this->cloudfrontHeaders = array();
// Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that
// start with cloudfront-.
foreach ($cfHeaders as $key => $value) {
if (substr(strtolower($key), 0, 16) === 'http_cloudfront_') {
$this->cloudfrontHeaders[strtoupper($key)] = $value;
* Retrieves the cloudfront headers.
public function getCfHeaders()
return $this->cloudfrontHeaders;
* @param string $userAgent
private function prepareUserAgent($userAgent) {
$userAgent = trim($userAgent);
$userAgent = substr($userAgent, 0, 500);
* Set the User-Agent to be used.
* @param string $userAgent The user agent string to set.
public function setUserAgent($userAgent = null)
// Invalidate cache due to #375
if (false === empty($userAgent)) {
return $this->userAgent = $this->prepareUserAgent($userAgent);
foreach ($this->getUaHttpHeaders() as $altHeader) {
if (false === empty($this->httpHeaders[$altHeader])) { // @todo: should use getHttpHeader(), but it would be slow. (Serban)
$this->userAgent .= $this->httpHeaders[$altHeader] . " ";
if (!empty($this->userAgent)) {
return $this->userAgent = $this->prepareUserAgent($this->userAgent);
if (count($this->getCfHeaders()) > 0) {
return $this->userAgent = 'Amazon CloudFront';
return $this->userAgent = null;
* Retrieve the User-Agent.
* @return string|null The user agent if it's set.
public function getUserAgent()
* Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
* self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
* @deprecated since version 2.6.9
* @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
* parameter is null which will default to self::DETECTION_TYPE_MOBILE.
public function setDetectionType($type = null)
$type = self::DETECTION_TYPE_MOBILE;
if ($type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED) {
$this->detectionType = $type;
public function getMatchingRegex()
return $this->matchingRegex;
public function getMatchesArray()
return $this->matchesArray;
* Retrieve the list of known phone devices.
* @return array List of phone devices.
public static function getPhoneDevices()
return self::$phoneDevices;
* Retrieve the list of known tablet devices.
* @return array List of tablet devices.
public static function getTabletDevices()
return self::$tabletDevices;
* Alias for getBrowsers() method.
* @return array List of user agents.
public static function getUserAgents()
return self::getBrowsers();
* Retrieve the list of known browsers. Specifically, the user agents.
* @return array List of browsers / user agents.
public static function getBrowsers()
* Retrieve the list of known utilities.
* @return array List of utilities.
public static function getUtilities()
* Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
* @deprecated since version 2.6.9
* @return array All the rules (but not extended).
public static function getMobileDetectionRules()
* Method gets the mobile detection rules + utilities.
* The reason this is separate is because utilities rules
* don't necessary imply mobile. This method is used inside
* the new $detect->is('stuff') method.
* @deprecated since version 2.6.9
* @return array All the rules + extended.
public function getMobileDetectionRulesExtended()