Скрипт для определения браузера пользователя на PHP

Недавно для одного проекта мне потребовалось сделать определение браузера и его версии на PHP.
Безуспешно просмотрев десятки устаревших скриптов, я решила написать свой собственный.
Чем он лучше других? Тем, что может определять не только основные браузеры (Firefox, Chrome, IE, Opera, Safari), но и те, которые построены на ядре Trident (Maxthon, Avant Browser, MyIE2) и Gecko (Konqueror, K-Meleon,Flock), и даже старые версии Оперы, маскирующиеся под IE. Кроме того, скрипт находит и отображает версию браузера.


Теория

Как определяется браузер на PHP?
В PHP есть замечательная переменная под названием $_SERVER['HTTP_USER_AGENT'].
У меня, например, она выглядит так:

Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10
Отсюда вытащить браузер и версию просто, не так ли?

Теперь IE 6

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
Здесь уже немного посложнее, но тоже не должно вызывать особых затруднений.

Opera 10.61

Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.6.30 Version/10.61
Опера приготовила нам подлянку: название браузера в начале, а версия, как это не странно, в конце.

Safari 5.1

Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8
Safari тоже удивляет: через слэш идёт вовсе не номер версии. Номер версии идёт чуть раньше.

Chrome 6.0.427.0

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.1 (KHTML, like Gecko) Chrome/6.0.427.0 Safari/534.1
Хром вытащить легче, хорошо бы ещё не перепутать его с Safari...

(О том, почему все браузеры (кроме Оперы) называют себя Mozilla можно в простой и увлекательной форме почитать здесь.)

Практика

Вы уже узнали, какое разнообразие в строке User-agent предлагают всего лишь пять браузеров.
Но в 9 из 10 случаев нас спасёт следующее регулярное выражение:
preg_match("/(MSIE|Opera|Firefox|Chrome|Version)(?:\/| )([0-9.]+)/", $agent, $browser_info);
После этого во втором элементе массива будет лежать название браузера, а в третьем — его версия.

Исключение представляет лишь Safari начиная с версии 3.0 и Opera начиная с версии 10.00.
Для них мы пишем:
if ($browser == 'Opera' && $version == '9.80') return 'Opera '.substr($agent,-5); // возвращаем версию Оперы в конце строки
if ($browser == 'Version') return 'Safari '.$version; // обозначаем браузер как Сафари
И ещё одна строка:
if (!$browser && strpos($agent, 'Gecko')) return 'Browser based on Gecko';
Если мы не смогли определить браузер, но знаем, что он использует ядро Gecko, то выводим сообщение о том, что браузер работает на этом ядре.
Вот, в сущности, и всё содержание первой, более компактной функции по определению браузера.
Её код целиком:
function user_min_browser($agent) {
	preg_match("/(MSIE|Opera|Firefox|Chrome|Version)(?:\/| )([0-9.]+)/", $agent, $browser_info);
	list(,$browser,$version) = $browser_info;
	if ($browser == 'Opera' && $version == '9.80') return 'Opera '.substr($agent,-5);
	if ($browser == 'Version') return 'Safari '.$version;
	if (!$browser && strpos($agent, 'Gecko')) return 'Browser based on Gecko';
	return $browser.' '.$version;
}
Вот более полная версия, позволяющая определять экзотические, устаревшие, а также те браузеры, которые построены на основе Firefox и IE:
function user_browser($agent) {
	preg_match("/(MSIE|Opera|Firefox|Chrome|Version|Opera Mini|Netscape|Konqueror|SeaMonkey|Camino|Minefield|Iceweasel|K-Meleon|Maxthon)(?:\/| )([0-9.]+)/", $agent, $browser_info); // регулярное выражение, которое позволяет отпределить 90% браузеров
        list(,$browser,$version) = $browser_info; // получаем данные из массива в переменную
        if (preg_match("/Opera ([0-9.]+)/i", $agent, $opera)) return 'Opera '.$opera[1]; // определение _очень_старых_ версий Оперы (до 8.50), при желании можно убрать
        if ($browser == 'MSIE') { // если браузер определён как IE
                preg_match("/(Maxthon|Avant Browser|MyIE2)/i", $agent, $ie); // проверяем, не разработка ли это на основе IE
                if ($ie) return $ie[1].' based on IE '.$version; // если да, то возвращаем сообщение об этом
                return 'IE '.$version; // иначе просто возвращаем IE и номер версии
        }
        if ($browser == 'Firefox') { // если браузер определён как Firefox
                preg_match("/(Flock|Navigator|Epiphany)\/([0-9.]+)/", $agent, $ff); // проверяем, не разработка ли это на основе Firefox
                if ($ff) return $ff[1].' '.$ff[2]; // если да, то выводим номер и версию
        }
        if ($browser == 'Opera' && $version == '9.80') return 'Opera '.substr($agent,-5); // если браузер определён как Opera 9.80, берём версию Оперы из конца строки
        if ($browser == 'Version') return 'Safari '.$version; // определяем Сафари
        if (!$browser && strpos($agent, 'Gecko')) return 'Browser based on Gecko'; // для неопознанных браузеров проверяем, если они на движке Gecko, и возращаем сообщение об этом
        return $browser.' '.$version; // для всех остальных возвращаем браузер и версию
}

Примеры работы

В таблице приведён результат работы двух функций - в первом столбце браузер, в котором вызывались функции, во втором - ответ функции, учитывающей малоизвестные браузеры, в третьей - результат работы сокращённой функции.

БраузерРезультат полной функцииРезультат сокращённой функции
Firefox 1.5.0.12Firefox 1.5.0.12Firefox 1.5.0.12
Firefox 3.0.10Firefox 3.0.10Firefox 3.0.10
Firefox 3.6.9Firefox 3.6.9Firefox 3.6.9
Firefox 4.0Firefox 4.0Firefox 4.0
IE 4.01IE 4.01MSIE 4.01
IE 5.5IE 5.5MSIE 5.5
IE 6.0IE 6.0MSIE 6.0
IE 7.0IE 7.0MSIE 7.0
IE 8.0IE 8.0MSIE 8.0
Chrome 5.0.375.127Chrome 5.0.375.127Chrome 5.0.375.127
Chromium 6.0.472.36Chrome 6.0.472.36Chrome 6.0.472.36
Chrome 7.0.517.8Chrome 7.0.517.8Chrome 7.0.517.8
Opera 7.03Opera 7.03MSIE 6.0
Opera 8.0Opera 8.0MSIE 6.0
Opera 8.54Opera 8.54Opera 8.54
Opera 9.50Opera 9.50Opera 9.50
Opera 10.00Opera 10.00Opera 10.00
Opera 10.10Opera 10.10Opera 10.10
Opera 10.61Opera 10.61Opera 10.61
Safari 3.0Safari 3.0Safari 3.0
Safari 4.0Safari 4.0Safari 4.0
Safari 5.0.1Safari 5.0.1Safari 5.0.1
Flock 1.2.6Flock 1.2.6Firefox 2.0.0.17
Epiphany 2.22Epiphany 2.22Firefox 2.0.0.20
Navigator 9.0.0.6Navigator 9.0.0.6Firefox 2.0.0.12
Netscape 8.1.3Netscape 8.1.3Browser based on Gecko
Konqueror 4.4Konqueror 4.4Browser based on Gecko
Galeon 2.0.4Browser based on GeckoBrowser based on Gecko
Iceape 1.1.13Browser based on GeckoBrowser based on Gecko
Iceweasel 3.0.4Iceweasel 3.0.4Browser based on Gecko
SeaMonkey 1.1.14SeaMonkey 1.1.14Browser based on Gecko
Minefield 3.7Minefield 3.7Browser based on Gecko
Avant Browser 7.0Avant Browser based on IE 7.0MSIE 7.0
Camino 2.0.4Camino 2.0.4Firefox 3.0.19

Красным цветом отмечены браузеры, которые функция не смогла определить.

А здесь вы можете проверить работу функций в своём браузере.
Надеюсь, что эти функции будут кому-то полезны.
Удачи.


Комментарии

30 октября 2010, 3:44 (Ответить)
Спасибо, классный скрипт. Единственный кто правильно определяет Оперу, т.к. в последних версиях число стоит в конце.
30 октября 2010, 9:05 (Ответить)
Андрей, невозможность определить Оперу другими скриптами и была причиной того, что я приступила к написанию собственного велосипеда :)
19 ноября 2010, 18:20 (Ответить)
Скрипт работает отлично, применил на своём сайте www.websr.ru/?go=searchsite&cid=115в разделе статистики поисковых запросов, хочу немного доработать его, чтобы в статистике выводилась картинка-иконка браузера.
19 ноября 2010, 20:35 (Ответить)
Я очень рада, что скрипт кому-то пригодился :)
28 ноября 2010, 23:42 (Ответить)
Мою opera-mini_5.1 for WM определяет как 10.54. Жаль
29 ноября 2010, 2:08 (Ответить)
Ну наконец-то кто-то сделал толковую функцию! recens, спасибо и вкусное пироженое за труды :)
Самое интересное, что функция весьма востребована, а в сети только какието протухшие обрубки валяются. Уже потерял терпение, когда заглянул сюда... И не жалею :)
2 декабря 2010, 17:25 (Ответить)
Александр, большое спасибо за такой отзыв. Буду стараться и дальше, чтобы людям не приходилось натыкаться на протухшие обрубки :)
28 января 2011, 8:30 (Ответить)
Я начинающий web мастер :). Изучая уроки, решил написать скрипт выявления типа браузера, но оказалось, что это не так просто(факт тому переменная $_SERVER['HTTP_USER_AGENT']). Зайдя сюда обнаружил очень правильный скрипт!!!
P.S. Простите за грамматические ошибки, если они есть :)
28 января 2011, 9:09 (Ответить)
Дмитрий, большое спасибо за отзыв!
P. S. Прощать не за что :)
7 февраля 2011, 22:40 (Ответить)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.6; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; eSobiSubscriber 2.0.4.16; .NET4.0C
то это значит ??? я ничего не понимаю, но очень нужно понять , могу определить точку доступа ?
7 февраля 2011, 23:46 (Ответить)
Нет, не можете. Если хотите определить страну/город по IP, то вам сюда: 2ip.ru
12 февраля 2011, 1:41 (Ответить)
Подскажите, пожалуйста, как вывести результат функции - чего нужно "echo" чтобы увидеть на странице?
12 февраля 2011, 10:28 (Ответить)
echo user_browser($_SERVER['HTTP_USER_AGENT']);
12 февраля 2011, 15:45 (Ответить)
Спасибо большое! работает!
16 февраля 2011, 0:56 (Ответить)
Zdravstvuite!
5 mesyaca nazad razoshlas' s parnem. Do sih por ne splyu normal'no. Sama seichas v Kitae, a paren' uehal k sebe v Maroko. U menya est' pochta na g-mail. I tam mozhno opredelit' IP- adres s kotorogo zahodili poslednie 10 raz.
Iz 10 polovina stoit moi adres i napisano Kitai, a ostal'nie vot takie :
65.55.41.68,
65.55.41.26,
65.55.41.77
POP3
i vsegda raznie. Zashla na etot sait , opredelyaet USA.
Vopros: Mozhet li bit' adres kak-to zakodirovan, i kakova veroyatnost'. Mozhet li eto bit' na samom dele Maroko ili Angliya.

P.S. Prostite za Chainikovskii vopros:)
16 февраля 2011, 1:23 (Ответить)
ya uzhe prochitala, chto IP adres mozhno legko izmenit')) No teper' vopros, a kto mozhet zahodit' na moyu pochtu, krome nego, da ewe i tak chasto? Mogut li eto bit' 'avtomati'?
19 августа 2011, 13:13 (Ответить)
Вешал виджеты на свой сайт www.barmaglotik.ru/magazin_odejdi.htmlи в разных браузерах они по разному отображались. Через JavaScript не нашел хорошего и точно скрипта да и в некоторых браузерах он вообще отключен.... Спасибо Вам огромное за такие труды, да воздастся Вам ;)
19 сентября 2011, 22:01 (Ответить)
Спасибо!
9 ноября 2011, 17:54 (Ответить)
Спасибо огромное
3 декабря 2011, 21:05 (Ответить)
С переходом на php 5.5 возникала ошибка, связанная с невозможностью работы устаревшей функции eregi(). Ваш скрипт помог решить проблему определения броузера. Спасибо огромное за труды!
7 декабря 2011, 4:28 (Ответить)
Замените строчки на
@list(,$browser,$version) = $browser_info;
if((string)$browser.(string)$version=='') return 'Other-0';

вылетает на неопределенном браузере
28 декабря 2011, 18:00 (Ответить)
Спасибо функция хорошо сделана.
история версий:
upload.wikimedia.org/wikipedia/commons/7/74/Timeline_of_web_browsers.svg

почему все браузеры мозила:
webew.ru/articles/1251.webew
15 января, 17:06 (Ответить)
Не ну вот так и знал что у меня он работать не будет. вот так и знал =( =( Просто пустой экран, белая страница и все, больше ничего непоказывает, права доступа 777 сделал, и все равно нефуричит ваш чудо скрипт =(
30 марта, 18:13 (Ответить)
Спасибо большое за функцию, еле нашел работающую...
10 апреля, 0:56 (Ответить)
Скажите можно ли адаптировать Ваш замечательный скрипт под браузеры современных мобильных телефонов? Например андроид передаёт в строке своё название... Если можно то как, или что нужно дописать? Спасибо! Отличный скрипт!

Добавить комментарий