Информация о пользователе на PHP

Недавно мне нужно было узнать название браузера посетителя сайта, для того чтобы запретить доступ к сайту определенному браузеру. Занятие глупое, т.к. любой пользователь на сайте должен чувствовать себя комфортно невзирая на каком он браузере, но с заказчиком не поспоришь, видимо дизайн сайта не работал под определенный браузер. В данном случае стоило сменить дизайнера а не жертвовать посетителями. Я не остановился только на определение браузера, мне хотелось добавить в него больше функционала для возможных будущих проверок. В итоге, класс получился весьма компактным и динамичным в изменениях.
На данный момент он выдает:

Название браузера
Версия браузера
Название операционной системы
Версия/ядро операционной системы
IP посетителя
проверка: зашел ли пользователь с браузера
проверка: зашел ли пользователь с мобильного устройства
Название марки/ос/браузера мобильного телефона, смартфона, планшета
проверка: является ли посетитель роботом поисковых систем
Какой поисковой системы принадлежит робот
Скачать класс с примером

Как работает PHP класс определение данных посетителя по user-agent
Из папки arrays загружаются ассоциативные массивы которые содержат аббревиатуры или короткие название браузеров, операционных систем или роботов которые встречаются в строке user-agent которую мы получаем от браузера.

После получения данных, динамично вызываются все методы которые имеют префикс set_ и заполняют переменные класса, т.к. только они являются публичными и можно вывести из за пределы видимости класса.

<?php
class AboutGuest {
 
    public $is_browser = False;
    public $is_mobile = False;
    public $is_robot = False;
 
    public $browsers = array();
    public $operating_systems = array();
    public $mobiles = array();
    public $robots = array();
 
    public $ip = '';
    public $version = '';
    public $browser = '';
    public $browser_full_name = '';
    public $operating_system = '';
    public $os_version = '';
    public $robot = '';
    public $mobile = '';
 
    public function __construct() {
        // Загружаем массивы для работы с данными
        $files = array('browsers', 'operating_systems', 'mobiles', 'robots');
        foreach($files as $file) {
            $this->load( $file );
        }
 
        // Данные пользователя
        $this->agent = (@$_SERVER['HTTP_USER_AGENT'])? $_SERVER['HTTP_USER_AGENT'] : '';
        // Вызываем методы для заполнения данных пользователя
        $setMethods = array('set_ip', 'set_browser', 'set_operating_system', 'set_robot', 'set_mobile');
        foreach($setMethods as $method) {
            $this->$method();
        }
    }
 
    private function load( $file_and_array_name ) {
        /*
         * Загружает массивы из папки с массивами
         */
        $Load = require_once( dirname( __FILE__ ) ) . '/arrays/'.$file_and_array_name.'.php';
        $this->$file_and_array_name = (!count($Load))? array() : $Load;
    }
 
    private function set_ip() {
        $this->ip = $_SERVER['REMOTE_ADDR'];
        return True;
    }
 
    private function set_browser() {
        if (is_array($this->browsers) and count($this->browsers) > 0) {
            foreach ($this->browsers as $key => $val) {
                if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match)) {
                    $this->is_browser = TRUE;
                    $this->version = $match[1];
                    $this->browser = $val;
                    $this->browser_full_name = $match[0];
                    return True;
                }
            }
        }
        return False;
    }
 
    private function set_operating_system() {
        if (is_array($this->operating_systems) AND count($this->operating_systems) > 0) {
            foreach ($this->operating_systems as $key => $val) {
                if (preg_match("|".preg_quote($key).".*?([a-zA-Z]?[0-9\.]+)|i", $this->agent, $match)) {
                    $this->operating_system = $val;
                    $this->os_version = $match[1];
                    return True;
                }
            }
        }
        $this->operating_system = 'Unknown';
    }
 
    private function set_robot() {
        if (is_array($this->robots) AND count($this->robots) > 0) {
            foreach ($this->robots as $key => $val) {
                if (preg_match("|".preg_quote($key)."|i", $this->agent)) {
                    $this->is_robot = TRUE;
                    $this->robot = $val;
                    return TRUE;
                }
            }
        }
        return FALSE;
    }
 
    private function set_mobile() {
        if (is_array($this->mobiles) AND count($this->mobiles) > 0) {
            foreach ($this->mobiles as $key => $val) {
                if (FALSE !== (strpos(strtolower($this->agent), $key))) {
                    $this->is_mobile = TRUE;
                    $this->mobile = $val;
                    return TRUE;
                }
            }
        }
        return FALSE;
    }
}
?>

Вот пример как выглядит массив с браузерами. Переменную которая будет содержать сам массив указывать не нужно, достаточно начать код с return. Если данный файл вызвать через require или require_once и результат выполнения присвоить переменной, то данная переменная будет содержать в себе массив (как это делает метод $this->load() в нашем классе).

<?php
return array(
    'Flock'     => 'Flock',
    'SeaMoney'  => 'SeaMonkey',
    'Chrome'    => 'Chrome',
    'Opera'     => 'Opera',
    'MSIE'      => 'Internet Explorer',
    'Internet Explorer' => 'Internet Explorer',
    'Shiira'    => 'Shiira',
    'Firefox'   => 'Firefox',
    'Chimera'   => 'Chimera',
    'Phoenix'   => 'Phoenix',
    'Firebird'  => 'Firebird',
    'Camino'    => 'Camino',
    'Netscape'  => 'Netscape',
    'OmniWeb'   => 'OmniWeb',
    'Safari'    => 'Safari',
    'Mozilla'   => 'Mozilla',
    'Konqueror' => 'Konqueror',
    'icab'      => 'iCab',
    'Lynx'      => 'Lynx',
    'Links'     => 'Links',
    'hotjava'   => 'HotJava',
    'amaya'     => 'Amaya',
    'IBrowse'   => 'IBrowse'
);
?>

Описание работы методов класса

Главный метод конструктор “__construct” в момент вызова класса AboutGuest он выполняется первым, тем самым играет ключевую роль в работе класса. Первым делом создает массивы данных для работы остальных методов. Объект $this->agent содежит в себе ничто иное как $_SERVER[‘HTTP_USER_AGENT’] которого мы получаем от браузера и из него вытаскиваем нужную нам информацию.

Метод $this->load( $file_and_array_name ) загрузчик

Данный метод загружает из папки arrays массивы и присваивает их переменной которая указана в значении атрибута $file_and_array_name, данных атрибут так же является и названием файла из папки arrays.

Метод $this->set_ip()

Возвращает значение из массива $_SERVER с ключом REMOTE_ADDR, как известно $_SERVER[‘REMOTE_ADDR’] это IP пользователя который доступен браузеру.

Метод $this->set_browser() файл массива: arrays / browsers.php

После того как метод $this->load загрузил массивы, данный метод будет работать с массивом из объекта $this->browsers. Как только он находит совпадение ключа массива с содержимым строки из $this->agent он принимает присваивает объекту $this->browser значение ключа из массива $this->browsers. Так, же данный метод присваивает и версию бразуера в $this->version. Так, как браузер уже нашел совпадение, не вызывает сомнения, что пользователь зашел с браузера а не выполнил заход на сайт через скрипт. Присваиваем $this->is_browser значение True;

Метод $this->set_operating_system() файл массива: arrays / operating_systems.php

Работает аналогично как как метод $this->set_browser за исключения того, что как массив проверки совпадении он пользуется объектом $this->operating_systems который получил массив из файла arrays/operating_systems.php после выполнения метода $this->load(). К сожалению, браузеры не столь активно деются с версией операционной системы и иногда можно получить непонятные цифры вместо версии. Так, что будете осторожны с когда пользуетесь $this->os_version. Название операционой системы содержится в $this->operating_system (не путать с $this->os_version)

Метод $this->set_robot() файл массива: arrays / robots.php

Проверяем если посетитель сайта не является роботом поисковых систем. Если он является роботом тогда значение для $this->is_robot будет TRUE; в значение $this->robot будет содержать название поисковика который запустил робота на сайт (Google Bot, Yandex Bot, Rambler Bot…)

Метод $this->set_mobile() файл массива: arrays / mobiles.php

Работает аналогично методу $this->set_operating_system(), только присваивает объекту $this->mobile название марки телефона и значение $this->is_mobile будет TRUE в случае захода с мобильного телефона, смартфона или планшета.
Пример работы:

<?php
header('Content-Type: text/html; charset=utf-8');
include_once('AboutGuest.php');
$AboutGuest = new AboutGuest;
echo   "Исходные данные: $AboutGuest->agent <br /><br />
        IP: $AboutGuest->ip
        Браузер: $AboutGuest->browser версия: $AboutGuest->version<br />
        Операционная система: $AboutGuest->operating_system версия: $AboutGuest->os_version<br /><br />
 
        Являюсь роботом? ". $AboutGuest->is_robot ."<br />
        Робот принадлежит: $AboutGuest->robot<br /><br />
 
        Зашел с мобильного? ". $AboutGuest->is_mobile ."<br />
        Телефон: $AboutGuest->mobile<br /><br />";
?>

Результат работы скрипта в разных браузерах может быть по разному. Причина в том, что браузеры не выдают PHP данные из $_SERVER[‘HTTP_USER_AGENT’] одинаково, в добавок, через CRON или file_get_contents можно отправить PHP любое искуственное значение для $_SERVER[‘HTTP_USER_AGENT’] и с эти уже ничего не поделать.

Результат выполнения скрипта в Firefox

Исходные данные: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:13.0) Gecko/20100101 Firefox/13.0.1
IP: 127.0.0.1
Браузер: Firefox версия: 13.0.1
Операционная система: Ubuntu версия: i686

Результат выполнения скрипта в Chrome

Исходные данные: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19 
IP: 127.0.0.1
Браузер: Chrome версия: 18.0.1025.168
Операционная система: Ubuntu версия: 12.04

Собственно все) код протестирован.
Спасибо “Блогу программиста” за хорошую старью.

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