Определение браузера на PHP

Головная боль всех профессиональных веб‑разработчиков – отличия внешнего вида html‑страниц в зависимости от браузера. Не будет преувеличением сказать, что каждый, кто занимается версткой, активно ненавидит не любит IE, однако, проблемы встречаются и у других браузеров.

На данный момент в среде верстальщиков правильным считается разделение содержимого страницы и ее оформления. Собственно, HTML содержит только информацию, а ее оформление описывается в CSS.

В связи с тем, что разные браузеры по‑разному интерпретируют инструкции оформления, верстальщики идут на хитрости, используя так называемые хаки – специфические методы написания CSS‑правил, при которых та или иная их (правил) часть воспринимается одним браузером, но не воспринимается другим. Самым знаменитым таким хаком является StarHtmlHack – конструкция, воспринимаемая только IE6:

*html .class {}

Для IE есть множество хаков, но для других браузеров их много меньше.

На мой взгляд гораздо безопаснее определить браузер пользователя и добавить к тегу <body> класс с именем этого браузера и, в отношении IE, его версией. В дальнейшем, в CSS очень легко прописать правила для соответствующего браузера.

Иногда я использую следующую конструкцию:

<body class="<?php 
if ( stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox') ) echo 'firefox';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'Chrome') ) echo 'chrome';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'Safari') ) echo 'safari';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'Opera') ) echo 'opera';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 6.0') ) echo 'ie6';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 7.0') ) echo 'ie7';
elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 8.0') ) echo 'ie8';
?>">

Далее, в CSS‑файле можно написать что‑то вроде:

.menu li {правила для всех браузеров}
.ie6	.menu li {исправления для IE6}
.opera	.menu li {исправления для Opera}

Этот метод ничуть не умаляет других способов: определение браузера средствами JS, использование условных комментариев, «чистых» и «грязных» хаков и пр.

Ничто не мешает использовать $_SERVER['HTTP_USER_AGENT'] для определения только одного проблемного браузера. К примеру, добавление правок только для Firefox 1.x будет выглядеть следующим образом:

<body class="<?php 
if ( stristr($_SERVER['HTTP_USER_AGENT'], 'Firefox/1') ) echo 'ff1';
?>">

И потом в CSS:

.ff1 .trouble {}

Удачной верстки! И пусть IE6 скорее умрет!


Связанные статьи

Комментарии (уже 39)

  1.  mmm (анонимно) (09.01.2010, 23:50)

    Спасибо! Полезный пост!
    Ссылка на комментарий #1
    Ответить
  2.  Steward (анонимно) (10.01.2010, 01:31)

    Ну это очень ненадёжный способ... сроку юзер-агента можно поменять в настройках. Сейчас это конечно редко кто делает - но раньше очень часто меняли родного юзер-агента на ИЕшного...
    Ссылка на комментарий #2
    Ответить
  3.  Николай Громов (10.01.2010, 01:37)

    @ Steward (анонимно):
    согласен, раньше часто меняли.
    сейчас, однако, мне сложно представить хоть сколько-нибудь реальную причину, которая может заставить менять строку юзерагента хотя бы 1% пользователей.

    п.с.: ранние версии IE специально писали в начале этой строки слово Mozilla, чтобы получать тот вариант страниц, который предназначен для Navigator-а от Netscape.
    Ссылка на комментарий #3
    Ответить
  4.  Cyber (анонимно) (15.01.2010, 01:26)

    Это у вас здесь на сайте уже стоит этот код? А то я думаю почему у меня в моем основном браузере, в котором изменена строка идентификации, ваш сайт загрузился только с третьего раза. Я уже подумал что хостинг тормозит. А нет, в других браузерах с первого раза загрузился. Так что да, вот я как раз меняю строку юзер-агента в браузере :)
    Ссылка на комментарий #4
    Ответить
  5.  Николай Громов (15.01.2010, 16:47)

    @ Cyber (анонимно):
    нет, на этом сайте такого кода нет.
    этот код ничуть не тормозит, выполняется без к-л проблем и очень быстро.
    проблемы с загрузкой сайта, скорее всего, были связаны с вашим каналом связи — ранее мне не встречались ни проблемы с загрузкой страниц, ни жалобы на такие проблемы. хотя, может и хостинг, черт его знает.
    о частоте встречаемости подмены строки юзер-агента спорить нечего — это, ориентировочно, менее 1% всех, кто пользуется интернетом. ибо мотива подменять эту строку сейчас уже нет.
    Ссылка на комментарий #5
    Ответить
  6.  40a (анонимно) (16.01.2010, 19:41)

    У меня в FireFox не работает
    Ссылка на комментарий #6
    Ответить
  7.  Николай Громов (18.01.2010, 14:15)

    @ 40a (анонимно):
    как проверяете?
    посмотрите что выдает Ваш браузер в строке юзер-агента: echo $_SERVER['HTTP_USER_AGENT'];
    Ссылка на комментарий #7
    Ответить
  8.  Комментатор 18 (02.02.2010, 19:16)

    Firefox 2 выдаёт: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.9) Gecko/20071025 FileDownloader;fdnet WebMoney Advisor
    Firefox 3 выдаёт: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.2) Gecko/2008091620 FileDownloader;fdnet FirePHP/0.2.4
    Ссылка на комментарий #8
    Ответить
  9.  Volday (24.02.2010, 04:42)

    Убил много времени, пока нашёл вашу статью. То что мне и было нужно.)) Только хочу сделать маленько по другому. Мне кажется лучше подключать не разные классы css, в зависимости от браузера, а подключать разные файлы css в начале. Пока интересует отдельный файл css для IE.
    Сделал, проверил, работает.)) Спасибо.
    Ссылка на комментарий #9
    Ответить
  10.  Николай Громов (24.02.2010, 23:50)

    @ Volday:
    все-таки, для IE лучше использовать конструкции наподобие
    <!--[if IE 7]><link href="css/ie7.css" rel="stylesheet" type="text/css" media="all" /><![endif]-->
    Ссылка на комментарий #10
    Ответить
  11.  shohrat (анонимно) (13.04.2010, 10:32)

    Очень полезная информация!
    Ссылка на комментарий #11
    Ответить
  12.  Stafox (анонимно) (02.06.2010, 11:21)

    Отличная статья! Сам давно пользовался этим скриптом, однако, подгружал отдельный css-файл. Идея делать класс для каждого браузера понравилась, возьму на заметку, спасибо!
    Ссылка на комментарий #12
    Ответить
  13.  Виктор (анонимно) (15.06.2010, 11:47)

    elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 8.0') ) echo 'ie8';
    elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 7.0') ) echo 'ie7';
    elseif ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE 6.0') ) echo 'ie6';

    надо переставить так т. к. в строчке 8 IE упоминается 6.0

    Ссылка на комментарий #13
    Ответить
  14.  Ваня (анонимно) (15.06.2010, 12:15)

    а у меня IE8 выдает строку: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0)
    IE6 не упоминается.
    зачем менять местами?
    Ссылка на комментарий #14
    Ответить
  15.  XJIOP (анонимно) (31.07.2010, 02:20)

    пример функции

    function browser($s) {
    if(substr($s,0,5) == "Opera")
    return "Opera";
    if(substr($s,0,7) == "Mozilla")
    return "Firefox";
    }
    echo browser($_SERVER['HTTP_USER_AGENT']);
    Ссылка на комментарий #15
    Ответить
  16.  Ghost (анонимно) (06.10.2010, 10:09)

    Мужик, ты гений
    Ссылка на комментарий #16
    Ответить
  17.  Юрий (анонимно) (13.12.2010, 20:58)

    8 ослик а выдает:
    Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; MRSPUTNIK 2, 2, 0, 94; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)
    Как так?
    Этот сайт в ие не открывается.
    Ссылка на комментарий #17
    Ответить
  18.  Николай Громов (14.12.2010, 00:35)

    @ Юрий (анонимно):
    у Вас стоит пакет эксплореров — видимо, на родной win XP с ее шестым ишаком, стоит пакет с 7кой и 8кой.
    если браузер один (не девелопперские машины), инфа о браузере не дублируется.

    да, в шестом говноишаке этот сайт не работает.
    Ссылка на комментарий #18
    Ответить
  19.  МасТЕРКо_О (анонимно) (21.03.2011, 22:34)

    Вот единственно, что у меня не работало при том, как написано в статье... но когда вписал всё вне (не как его клас) - всё заработало)
    а
    так
    статейка очень полезная. спасибо
    Ссылка на комментарий #19
    Ответить
  20.  Newday (26.04.2011, 13:36)

    Спасибо! Очень помог. С утра искал в интернете, но только этот мне понравился!
    Ссылка на комментарий #20
    Ответить
  21.  Екатерина (анонимно) (20.10.2011, 07:16)

    А у меня некорректная идентификация браузера,говорят.На некоторых сайтах не могу загружать файлы и вообще.Но вот этот сайт отобразился отлично.И как же быть?Спасибо.
    Ссылка на комментарий #21
    Ответить
  22.  Николай Громов (20.10.2011, 15:00)

    @ Екатерина (анонимно):
    о функциональности сайтов, в зависимости от браузера — это, конечно, к создателям этих сайтов нужно обращаться.
    универсальный ответ на вопрос «что делать» в данном случае таков: используйте хороший современный, распространенный (удобный, быстрый и безопасный) браузер — Firefox или Google Chrome.
    Ссылка на комментарий #22
    Ответить
  23.  Екатерина (анонимно) (21.10.2011, 07:01)

    @ Николай Громов:
    Спасибо за ответ.Этими браузерами и пользуюсь.Вот про Firefox на некоторых сайтах мне и говорят,что некорректен.В основном работает отлично.Обновлен до последней версии.И когда мне сообщили о некорректности браузера-очень была удивлена.В связи с этим и искала в инете инфу на эту тему.Статья у вас подходящая,конечно.Спасибо.
    Ссылка на комментарий #23
    Ответить
  24.  Николай Громов (21.10.2011, 14:58)

    @ Екатерина (анонимно):
    если сайт пишет, что Ваш Firefox 7.0.1 некорректен, сайт — г@вно, автор сайта — муд@к.
    Ссылка на комментарий #24
    Ответить
  25.  Олег (анонимно) (08.11.2011, 02:35)

    чтобы умер броузер особенно такой большой слон как ie6 нужно только время и ничего другого, а вот чтобы не плодились всякие броузеры со своей спецификой для этого все верстальщикам не нужно вестись, а нужно дружно объявить бойкот таким броузерам, которые не отвечают спецификации, а не вставлять бесконечные костыли и хаки. тогда действительно кривые броузеры вымрут :) правда могут остаться без работы многие верстальщики...
    а скрипт действительно полезный, вообще php гораздо стабильнее и кроссплатформеннее чем html & js так, что может стоит изучить учебник http://d86.ru/g1091476 по php и забыть как страшный сон все костыли и хаки!?
    Ссылка на комментарий #25
    Ответить
  26.  Олег (анонимно) (08.11.2011, 02:40)

    кстати, определить версию броузера можно на js и уже в загрузившейся странице установить класс для тега body
    Ссылка на комментарий #26
    Ответить
  27.  Олег (анонимно) (08.11.2011, 02:42)

    чтобы умер броузер особенно такой большой слон как ie6 нужно только время и ничего другого, а вот чтобы не плодились всякие броузеры со своей спецификой для этого все верстальщикам не нужно вестись, а нужно дружно объявить бойкот таким броузерам, которые не отвечают спецификации, а не вставлять бесконечные костыли и хаки. тогда действительно кривые броузеры вымрут :) правда могут остаться без работы многие верстальщики...
    а скрипт действительно полезный, вообще php гораздо стабильнее и кроссплатформеннее чем html & js так, что может стоит изучить учебник http://d86.ru/g1091476 по php и забыть как страшный сон все костыли и хаки!?

    кстати, определить версию броузера можно на js и уже в загрузившейся странице установить класс для тега body
    Ссылка на комментарий #27
    Ответить
  28.  ХеХе (анонимно) (25.11.2011, 17:16)

    Юзерагент менять есть смысл даже сейчас, когда такие компании как Гугл блокируют функцию "поиск похожего изображения" для пользователей оперы последней версии.
    Ссылка на комментарий #28
    Ответить
  29.  k313 (анонимно) (25.11.2011, 20:05)

    IE 8 выдал :
    Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) )

    поэтому думаю начинать надо с :
    if ( stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE ') ) echo 'ie';

    а уже потом все остальные...
    Ссылка на комментарий #29
    Ответить
  30.  Николай Громов (25.11.2011, 20:11)

    @ ХеХе (анонимно):
    у Оперы всегда были проблемы с JS.
    на данный момент, определение юзерагента, как программистская задача, актуальна, преимущественно для выявления Internet Explorer-ов — медленных дырявых браузеров, не поддерживающих новые возможности веб-разработки.
    Ссылка на комментарий #30
    Ответить
  31.  Николай Громов (25.11.2011, 20:15)

    @ Николай Громов:
    у Вас в системе, видимо, стоит IE6, а IE8 — как часть одного из комплектов IE (IETester, Multiple IE)?
    с чего в этом коде начинать — без разницы.
    в Вашем варианте IE будет определен без версий, а при попытке определить версию, всегда будет выдаваться 6-ка.
    Ссылка на комментарий #31
    Ответить
  32.  k313 (анонимно) (25.11.2011, 20:56)

    да я просто боюсь, что скоро IE будет в юзер-агенте всё что не попадя прописывать ( и "Firefox", и "Opera", и тд)... вот и ставлю его на первое место, может пригодиться...
    <BODY class='<?php
    function myfunc1($s) {if(($a=abs($s{0}))>0 || ($a=abs($s{1}))>0) return $a; else return "";}
    if(($ss=strstr($s=strtolower($_SERVER['HTTP_USER_AGENT']),"msie"))) echo "ie".myfunc1(substr($ss,4,2));
    elseif(($ss=strstr($s,"firefox"))) echo "ff".myfunc1(substr($ss,7,2));
    elseif(($ss=strstr($s,"opera"))) echo "op".myfunc1(substr($ss,5,2));
    else echo "all";
    ?>'>
    Ссылка на комментарий #32
    Ответить
  33.  Николай Громов (25.11.2011, 22:12)

    @ k313 (анонимно):
    думаю, этого не произойдет.
    а если и произойдет, сейчас уже есть короткие, эффективные и точные методы определения браузеран а стороне пользователя.
    Ссылка на комментарий #33
    Ответить
  34.  ZiPP Stealth iXplo (анонимно) (07.12.2011, 22:46)

    Спасибо, отличный простой пример для современных браузеров. Так и надо. Удачи тебе, автор )
    Ссылка на комментарий #34
    Ответить
  35.  k313 (анонимно) (02.01.2012, 22:28)

    Кстати вот нашел на просторах интернета:
    http://intsystem.org/141/user-browser-detect/

    Пишут очень удобный класс для определения браузера. Попробовал - вроде не глючит.
    Ссылка на комментарий #35
    Ответить
  36.  k313 (анонимно) (19.01.2012, 09:45)

    @ k313 (анонимно):
    Эээээ!!! то что сверху от k313 - я этого не писал! Какой-то лже-k313...
    Ссылка на комментарий #36
    Ответить
  37.  k313 (анонимно) (19.01.2012, 10:48)

    код я переписал...
    =========
    if(($s1=stristr($s2=$_SERVER['HTTP_USER_AGENT'],'MSIE'))) {$usag='ie';}
    elseif(($s1=stristr($s2,'Chrome'))) {$usag='ch';}
    elseif(($s1=stristr($s2,'Opera'))) {$usag='op';}
    elseif(($s1=stristr($s2,'Firefox'))) {$usag='ff';}
    elseif(($s1=stristr($s2,'Safari'))) {$usag='sf';}
    else {$usag='al';$usagver=false;}
    if($usag!='al') {if(($s3=stristr($s2,'Version'))) {$usagver=myfunc1($s3);} else {$usagver=myfunc1($s1);}}
    function myfunc1($s) {
    $arr=array(0,0,0);
    for($b=$j=$i=0;($i0) {$j++; $b=0;}}//
    return $arr;
    }
    ===========
    и кстати статейка, после которой ещё меньше хочется определять user_agent на стороне сервера...
    http://webew.ru/articles/1251.webew
    Ссылка на комментарий #37
    Ответить
  38.  k313 (анонимно) (19.01.2012, 10:50)

    echo 'HTTP_USER_AGENT = '.$_SERVER['HTTP_USER_AGENT'].'<p>user_agent = '.$usag.'
    Version = '.$usagver[0].'.'.$usagver[1].'.'.$usagver[2];
    Ссылка на комментарий #38
    Ответить
  39.  k313 (анонимно) (19.01.2012, 17:50)

    на сайте теги не преобразовываются, нормально код показать нет возможности. Админ, исправте пожалуйста.
    ======================
    может так покажет правильно...

    function myfunc1($s) {$arr=array(0,0,0); for($b=$j=$i=0;($i<16 && $j<3);$i++) {if(($a=abs($s{$i}))>0 || $s{$i}==='0') {$arr[$j]=$arr[$j]*pow(10,$b)+$a; $b++;} elseif($b>0) {$j++; $b=0;}} return $arr;}
    Ссылка на комментарий #39
    Ответить

Ваш комментарий

Комментарий будет опубликован после проверки.



При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где можно изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д.







(обязательно)


Дополнительно

RSS-подписка

В этом блоге две категории