The OpenNET Project
 
Поиск (ключи):    ПРОГРАММЫ СТАТЬИ СОВЕТЫ ФОРУМ
  WIKI НОВОСТИ (+) MAN'ы ДОКУМЕНТАЦИЯ

Ускорение get_browser() в PHP
В PHP есть очень удобная для разного рода статистики машин функция - get_browser(). 
Она возвращает по юзерагенту объект, содержащий отфильтрованный набор информации 
о браузере и его системе, как то имя, платформа, версия и т.п. "Т.п." - это набор информации, 
о поддержке кук, дотнета и еще кучи всего, мне не нужного.

Недавно заметил, что при большом количестве обращений эта функция довольно
медленная и ресурсоемкая.
Как положено, полез на http://www.php.net/get_browser читать, что пишут в комментариях.

Первое, что попробовал, перейти на облегченную версию browscap.ini... 
Помогло... процентов на 5 frown.gif
В коментах нашел Browser Capabilities PHP Project. По заявлениям автора одни из основных фитч 
- быстрота и полная совместимость с get_browser().

Мне так-же понравилось автоматическое обновление browscap.ini.

С совместимостью оказалось не все гладко. Если у get_browser() все свойства написаны строчными,
то у данного проекта их названия пишутся с большой буквы,
следовательно совместимость не полная. Но, это не самая большая проблема и легко обходится.

Но вот со скоростью всплыли неожиданные проблемы.
Даже после накопления кеша производительность не увеличилась и осталась на уровне get_browser()

Для себя решил эту проблему след. образом:

таблица в mysql:

CREATE TABLE `bc_cache` (
  `cache_id` bigint(16) unsigned NOT NULL auto_increment,
  `hash` char(32) NOT NULL default '',
  `browser` char(32) NOT NULL default '',
  `version` char(32) NOT NULL default '',
  `platform` char(32) NOT NULL default '',
  PRIMARY KEY  (`cache_id`),
  UNIQUE KEY `hash` (`hash`)
)

Код в PHP примерно такой:

$ua_hash = bin2hex(mhash(MHASH_MD5,$_SERVER['HTTP_USER_AGENT']));
$query = sprintf("select browser,version,platform from bc_cache where hash='%s'",$ua_hash);
$data = mysql_query($query,$res);
if (mysql_num_rows($data)) {
    $browser = mysql_result($data,0,'browser');
    $version = mysql_result($data,0,'version');
    $platform = mysql_result($data,0,'platform');
} else {
    $bc = get_browser($useragent);
    $browser = $bc->browser;
    $version = $bc->version;
    $platform = $bc->platform;
    $query = sprintf("insert into bc_cache (hash,browser,version,platform) values ('%s','%s','%s','%s')",
                        $ua_hash,
                        $browser,
                        $version,
                        $platform);
    mysql_unbuffered_query($query);
}

В дальнейшем пользуюсь переменными $browser,$version и $platform как мне заблагорассудится.

Результат - повышение производительности, на глаз, раза в 4-8.

Почему? За счет того, что $_SERVER['HTTP_USER_AGENT'] хоть и может сильно различаться, 
но всё-таки, вещь не самая уникальная. А select по уникальному индексу по
char(32) отрабатывает очень быстро!
 
09.01.2008 , Автор: kornel , Источник: http://bb.ct.kz/index.php?automodul...
Раздел:    Корень / Программисту и web-разработчику / PHP / Конструкции языка и функции

Обсуждение [ RSS ]
 
  • 1, Antrew, 08:09, 11/01/2008 [ответить] [смотреть все]
  • +/
    да.... тяжело бывает не знать что такое регулярные выражения
     
     
  • 4, Антон, 10:52, 11/01/2008 [^] [ответить] [смотреть все]
  • +/
    >да.... тяжело бывает не знать что такое регулярные выражения

    Там задача не только строку user_agent разобрать, но и по ключу найти параметры браузера из базы. Стандартный get_browser, как я понял, на каждый запрос парсит текстовый файл browscap.ini с базой параметров, килобайт 400.

     
  • 2, klubben, 08:26, 11/01/2008 [ответить] [смотреть все]
  • +/
    Жуть :)
    p.s. А кто сказал что хэш уникальный?
     
  • 3, switch, 09:18, 11/01/2008 [ответить] [смотреть все]
  • +/
    Идея не нова. В скорости возможно и есть выиграш на глаз, но думаю узкое место будет mhash. По двум причинам, как сказали - это действительно не уникально, второе - эта функция не из быстрых.
     
  • 5, BigNest, 17:30, 11/05/2010 [ответить] [смотреть все]
  • +/
    В указанном коде возможна SQL-инъекция путём подстановки произвольного UAgent.
     

    Ваш комментарий
    Имя:         
    E-Mail:      
    Заголовок:
    Текст:

     Добавить заметку
     Версия для печати
     
     Поиск заметки:
     

    Последние заметки
    - 12.05 Организация шифрованного бэкапа с помощью rdiff-backup, encfs и Dropbox
    - 11.05 Настройка беспроводного соединения в Debian GNU/Linux
    - 07.05 Использование Google Drive в Linux
    - 18.04 Использование нескольких сетевых стеков в Linux
    - 15.04 Восстановление стандартного KDE меню после его удаления (например, wine)
    - 11.04 Настройка gmirror при использовании GPT во FreeBSD 9
    - 09.04 Маршрутизатор на базе FreeBSD с приоритизация трафика средствами PF и ALTQ
    - 02.04 Частичное восстановление данных MySQL из бэкапа, созданного с использованием LVM
    - 21.03 Настройка DNSSEC в BIND 9.9
    - 17.03 Набор номера на Cisco IP Phone 7960/7940 из скрипта
    RSS | Следующие 15 записей >>


    ПОДПИШИСЬ НА ЖУРНАЛ Linux Format 2012!

    Журнал "Linux Format" (Линукс Формат)- Единственный в России и странах СНГ журнал на русском языке, посвящённый Linux и свободному ПО. Журнал для IT-директоров, IT-менеджеров, программистов, системных администраторов, учителей школ и преподавателей ВУЗов и всех пользователей ПК. В каждом выпуске: Новости индустрии OpenSource, обзоры новинок свободного ПО, обучающие и методические статьи.

    Каждый, кто оформит подписку, получает бонусы и подарки- объёмные наклейки на системный блок, диск с архивом номеров за 2005-2011 г.г. и ежемесячно электронную версию журнала в pdf-формате.

    Оформить подписку на год


      Закладки на сайте
      Проследить за страницей
    Created 1996-2012 by Maxim Chirkov  
    ДобавитьРекламаВебмастеруГИД  
    RUNNet TopList