За последние 24 часа нас посетили 16311 программистов и 1582 робота. Сейчас ищут 1550 программистов ...

Регулярка не распознаёт версию Oper'ы :(

Тема в разделе "Регулярные выражения", создана пользователем Zagin, 24 фев 2023.

  1. Zagin

    Zagin Новичок

    С нами с:
    24 фев 2023
    Сообщения:
    3
    Симпатии:
    0
    Приветствую всех!
    Мне удалось найти в Интернете https://stackoverflow.com/questions/8754080/how-to-get-exact-browser-name-and-version php-функцию определения браузера, умеющую отличать даже браузер Opera, но при этом эта функция почему-то не хочет читать версию Oper'ы. Версию других браузеров (я проверял ещё Firefox и Edge) определяет на ура, а вот Оперную версию - игнорирует, хотя видимых отличий в её написании от версий Firefox и Edge в строке HTTP_USER_AGENT - нет.
    Помогите разобраться, пожалуйста. Ниже привожу код функции и её вызова:

    PHP:
    1. function getBrowser1() {
    2.     $u_agent = $_SERVER['HTTP_USER_AGENT'];
    3.     $bname = 'Unknown';
    4.     $platform = 'Unknown';
    5.     $version= "";
    6.     if (preg_match('/linux/i', $u_agent)) {// First get the platform?
    7.         $platform = 'linux';
    8.     } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
    9.         $platform = 'mac';
    10.     } elseif (preg_match('/windows|win32/i', $u_agent)) {
    11.         $platform = 'windows';
    12.     };
    13.     if(preg_match('/MSIE/i',$u_agent) && !preg_match('/Opera/i',$u_agent)) {// Next get the name of the useragent yes seperately and for good reason
    14.         $bname = 'Internet Explorer';
    15.         $ub = "MSIE";
    16.     } elseif(preg_match('/Firefox/i',$u_agent)) {
    17.         $bname = 'Mozilla Firefox';
    18.         $ub = "Firefox";
    19.     } elseif(preg_match('/OPR/i',$u_agent)) {
    20.         $bname = 'Opera';
    21.         $ub = "Opera";
    22.     } elseif(preg_match('/Chrome/i',$u_agent) && !preg_match('/Edg/i',$u_agent)) {
    23.         $bname = 'Google Chrome';
    24.         $ub = "Chrome";
    25.     } elseif(preg_match('/Safari/i',$u_agent) && !preg_match('/Edg/i',$u_agent)) {
    26.         $bname = 'Apple Safari';
    27.         $ub = "Safari";
    28.     } elseif(preg_match('/Netscape/i',$u_agent)) {
    29.         $bname = 'Netscape';
    30.         $ub = "Netscape";
    31.     } elseif(preg_match('/Edg/i',$u_agent)) {
    32.         $bname = 'Edge';
    33.         $ub = "Edg";
    34.     } elseif(preg_match('/Trident/i',$u_agent)) {
    35.         $bname = 'Internet Explorer';
    36.         $ub = "MSIE";
    37.     }; // finally get the correct version number:
    38.     $known = array('Version', $ub, 'other');
    39.     $pattern = '#(?<browser>' . join('|', $known) .     ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
    40.     if (!preg_match_all($pattern, $u_agent, $matches)) {
    41.         // we have no matching number just continue
    42.     }; // see how many we have:
    43.     $i = count($matches['browser']);
    44.     if ($i != 1) {//we will have two since we are not using 'other' argument yet //see if version is before or after the name
    45.         if (strripos($u_agent,"Version") < strripos($u_agent,$ub)) {
    46.             $version = (!empty($matches['version']) ? $matches['version'][0] : '');
    47.         } else {
    48.             $version = (!empty($matches['version']) ? $matches['version'][1] : '');
    49.         };
    50.     } else {
    51.     //$version = (!empty($matches['version']) ? $matches['version'][0] : '');
    52.     }; // check if we have a number:
    53.     if ($version==null || $version=="") {
    54.         $version="?";
    55.     };
    56.     return [
    57.         'userAgent' => $u_agent,
    58.         'name'      => $bname,
    59.         'version'   => $version,
    60.         'platform'  => $platform,
    61.         'pattern'    => $pattern
    62.     ];
    63. }
    64. // invoke function
    65. $arBrowser =  getBrowser1();
    66. echo '<pre>';
    67. print_r($arBrowser);
    68. echo '</pre>';
     
  2. Survivor

    Survivor Новичок

    С нами с:
    8 фев 2023
    Сообщения:
    86
    Симпатии:
    17
    А догадаться и посмотреть, что лежит в "$u_agent" ?

    PHP:
    1. //- var_dump ( $u_agent );
    2.  
    3. //- Opera =>
    4. 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 OPR/95.0.0.0'
    5.  
    6. //- Chrome
    7. 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
    И зачем в принципе это извращение, если юзер агент подделывается в два счета? Практической пользы не вижу.

    p.s.
    Т.к. ты проверяешь через If else, то проверяй сначала OPR, а потом мазилу/хром
     
    #2 Survivor, 25 фев 2023
    Последнее редактирование: 25 фев 2023
  3. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    911
    Симпатии:
    143
    Как минимум этот танец с бубном нужно на клиенте исполнять, а так легче гугланал какой-нить прикрутить, там-то точно собаку съели для защиты от ботов.
     
  4. Zagin

    Zagin Новичок

    С нами с:
    24 фев 2023
    Сообщения:
    3
    Симпатии:
    0
    Мне это нужно для предварительной идентификации пользователя в одном из скриптов.
    Написал же: "...видимых отличий в её написании от версий Firefox и Edge в строке HTTP_USER_AGENT - нет" - просто поверьте, что это я не с потолка взял, а именно из 'посмотреть, что лежит в "$u_agent"'

    Вы правы - подделать можно всё: и IP-шник, и агента, и сигнификатор ОС, и много ещё чего. Но прежде - нужно догадаться, что именно из перечисленного (и не перечисленного) зашифровано для идентификации. В конце-концов - такой подбор не является ни быстрым, ни лёгким. Делается ставка именно на его (НЕ)целесообразность.
    Спасибо за участие, но хотелось бы получить совет именно по конкретной регулярке.
     
  5. Survivor

    Survivor Новичок

    С нами с:
    8 фев 2023
    Сообщения:
    86
    Симпатии:
    17
    Кстати, есть встроенная в php функция get_browser
    https://www.php.net/manual/en/function.get-browser.php
    но она определяет браузер Opera как Chrome, а все потому, что движок хромиум и там, и там))

    PHP:
    1. function getBrowser1()
    2. {
    3.     $u_agent   = $_SERVER['HTTP_USER_AGENT'];
    4.     $bname     = 'Unknown';
    5.     $platform  = 'Unknown';
    6.     $version   = "";
    7.  
    8.     if (preg_match('/linux/i', $u_agent))
    9.     {
    10.         $platform = 'linux';
    11.     }
    12.     elseif (preg_match('/macintosh|mac os x/i', $u_agent))
    13.     {
    14.         $platform = 'mac';
    15.     }
    16.     elseif (preg_match('/windows|win32/i', $u_agent))
    17.     {
    18.         $platform = 'windows';
    19.     }
    20.  
    21.  
    22.     if( preg_match('/MSIE/i',$u_agent) && !preg_match('/Opera/i',$u_agent) )
    23.     {
    24.         $bname = 'Internet Explorer';
    25.         $ub = "MSIE";
    26.     }
    27.     elseif( preg_match('/Firefox/i',$u_agent) )
    28.     {
    29.         $bname = 'Mozilla Firefox';
    30.         $ub = "Firefox";
    31.     }
    32.     elseif( preg_match('/OPR/i',$u_agent) )
    33.     {
    34.         $bname = 'Opera';
    35.         //$ub = "Opera";
    36.         $ub = 'OPR';
    37.     }
    38.     elseif( preg_match('/Chrome/i',$u_agent) && !preg_match('/Edg/i',$u_agent) )
    39.     {
    40.         $bname = 'Google Chrome';
    41.         $ub = "Chrome";
    42.     }
    43.     elseif( preg_match('/Safari/i',$u_agent) && !preg_match('/Edg/i',$u_agent) )
    44.     {
    45.         $bname = 'Apple Safari';
    46.         $ub = "Safari";
    47.     }
    48.     elseif( preg_match('/Netscape/i',$u_agent) )
    49.     {
    50.         $bname = 'Netscape';
    51.         $ub = "Netscape";
    52.     }
    53.     elseif( preg_match('/Edg/i',$u_agent) )
    54.     {
    55.         $bname = 'Edge';
    56.         $ub = "Edg";
    57.     }
    58.     elseif( preg_match('/Trident/i',$u_agent) )
    59.     {
    60.         $bname = 'Internet Explorer';
    61.         $ub = "MSIE";
    62.     }
    63.  
    64.     $known   = ['Version', $ub, 'other'];
    65.     $pattern = '#(?<browser>' . join('|',$known).')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
    66.  
    67.     if (!preg_match_all($pattern, $u_agent, $matches)) {
    68.         // we have no matching number just continue
    69.     } // see how many we have:
    70.  
    71.  
    72.     $i = count($matches['browser']);
    73.  
    74.     $version = ( !empty($matches['version']) ? $matches['version'][0] : '');
    75.  
    76.     if ( $version == null || $version == "" )
    77.     {
    78.         $version = "?";
    79.     }
    80.  
    81.     return
    82.     [
    83.         'userAgent' => $u_agent,
    84.         'name'      => $bname,
    85.         'version'   => $version,
    86.         'platform'  => $platform,
    87.         'pattern'    => $pattern
    88.     ];
    89. }
    Проверил: chrome, opera, edge
     
  6. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    911
    Симпатии:
    143
    ТС, после замены на "$ub="OPR";" регулярка ловит версию, но вот это
    PHP:
    1.     $i = count($matches['browser']);
    2.     if ($i != 1) {//we will have two since we are not using 'other' argument yet //see if version is before or after the name
    3.         if (strripos($u_agent,"Version") < strripos($u_agent,$ub)) {
    4.             $version = (!empty($matches['version']) ? $matches['version'][0] : '');
    5.         } else {
    6.             $version = (!empty($matches['version']) ? $matches['version'][1] : '');
    7.         };
    8.     } else {
    9.     //$version = (!empty($matches['version']) ? $matches['version'][0] : '');
    10.     }; // check if we have a number:
    11.     if ($version==null || $version=="") {
    12.         $version="?";
    13.     };
    её обратно в "?" превращает, давай сам уже в отладку своего кода.
     
  7. Zagin

    Zagin Новичок

    С нами с:
    24 фев 2023
    Сообщения:
    3
    Симпатии:
    0
    To Survivor, don.bidon:
    Большое вам спасибо за участие и дельные подсказки!
    Теперь мне удалось подправить все мои определения, как и хотелось.
    Прошу считать проблему решённой.
    Ещё раз благодарю.