Joomla API

JInput - получение и фильтрация переменных запроса

Joomla

Общая информация

Группа классов Input абстрагирует внешние данные (переменные запроса), которые находятся в суперглобальных массивах (таких как $_POST, $_GET, $_COOKIE, $_FILES) и является составляющей не только Joomla! CMS, но и Joomla! Framework.

В CMS эта группа классов расположена в /libraries/joomla/input и состоит из главного класса JInput и четырех дочерних классов, которые его расширяют:

  • JInput – базовый класс, предназначен для работы с $_REQUEST ($_POST, $_GET и $_COOKIE), предоставляет удобный доступ ко всем дочерним классам и суперглобальным массивам;
  • JInputСli – класс предназначен для работы с командной строкой;
  • JInputCookie – класс предназначен для работы $_COOKIE;
  • JInputFiles – класс предназначен для работы с $_FILES;
  • JInputJson – класс предназначен для работы с JSON-данными.

Для эффективной фильтрации переменных запроса при их получении они используют класс JFilterInput. Класс JFilterInput расположен в файле /libraries/joomla/filter/input.php.

На практике чаще всего используется класс JInput. В Joomla 2.5 этот класс пришел на замену JRequest. Экземпляр класса (объект) JInput является публичным свойством, которое доступно из Приложения (Application). Для использования JInput необходимо вызвать следующий код:

$jinput = JFactory::getApplication()->input;

Начиная с Joomla 3 при разработке компонента к объекту JInput можно обращаться не из Приложения, а как к свойству input объекта контроллера класса JControllerLegacy (если ваши контроллеры расширяют класс JControllerLegacy, а это обычная практика). То есть вместо JFactory::getApplication()->input в контроллере можно использовать просто $this->input.

Получение значения

Получить значение из JInput можно с помощью метода get():

$source = $jinput->get('varname', 'default_value', 'filter');

Первый параметр – это имя переменной в запросе, второй параметр – это значение по умолчанию, а третий параметр – это тип фильтра, который будет применен к получаемому значению переменной. По умолчанию фильтр настроен на тип cmd.

Предположим, что мы получаем из запроса следующую строку:

..-123 AaBb ДдГг = [] () + ^ * _ . % - <meta content="Joomla" name="generator" />

Ниже представлены все доступные типы фильтров и отфильтрованная с их помощью строка:

  • INT, INTEGER – первое целое число
    int(-123)
  • UINT - первое беззнаковое целое число
    int(123)
  • FLOAT, DOUBLE - первое число с плавающей точкой
    float(-123)
  • BOOL, BOOLEAN – конвертирует значение в булев тип
    bool(true)
  • WORD – только латинские буквы и нижнее подчеркивание
    string(35) "AaBb_metacontentJoomlanamegenerator"
  • ALNUM - только латинские буквы и цифры
    string(37) "123AaBbmetacontentJoomlanamegenerator"
  • CMD - только латинские буквы, нижнее подчеркивание, тире и точка. Убирает ведущие точки.
    string(41) "-123AaBb_.-metacontentJoomlanamegenerator"
  • BASE64 - только латинские буквы, косая черта, знак плюса и знак равно
    string(42) "123AaBb=+metacontent=Joomlaname=generator/"
  • STRING – конвертирует в чистую строку, убирает все теги и атрибуты
    string(43) "..-123 AaBb ДдГг = [] () + ^ * _ . % - "
  • HTML – конвертирует в строку, убирает все HTML теги и атрибуты. Во время обработки проверяет наличие разрешенных тегов/атрибутов. Если они есть, то их не убирает.
    string(43) "..-123 AaBb ДдГг = [] () + ^ * _ . % - "
  • ARRAY – конвертирует в массив без применения фильтрации
    array(1) { [0]=> string(85) " ..-123 AaBb ДдГг = [] () + ^ * _ . % - <meta content="Joomla" name="generator" />" }
  • PATH – конвертирует в строку и валидирует как путь до папки или файла (например path/to/file.png или path/to/dir). Не принимает абсолютный путь или путь, который заканчивается косой чертой.
    string(0) ""
  • USERNAME – удаляет все невалидные для имени пользователя символы (\x00, -, \x1F, \x7F, <, >, ", ', %, &)
    string(78) "..-123 AaBb ДдГг = [] () + ^ * _ . - meta content=Joomla name=generator /"
  • RAW – фильтрация не применяется. Доступен начиная с Joomla 3.
    string(85) " ..-123 AaBb ДдГг = [] () + ^ * _ . % - <meta content="Joomla" name="generator" />"

Примеры получения значения

// Получаем переменную "view"
$view = $jinput->get('view'); 

// Если переменная "view" недоступна, используем значение по умолчанию
$view = $jinput->get('view', 'display'); 

// Получаем значение и явно применяем фильтр
$id = $jinput->get('id', null, 'int');
$text = $jinput->get('text', null, 'RAW');

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

// Применяем тип фильтра "INT"
$id = $input->getInt('id'); 

// Применяем тип фильтра "WORD"
$folder = $input->getWord('folder', 'images'); 

// Применяем тип фильтра "USERNAME"
$login = $input->getUsername('login');

Получение нескольких значений

Для получения сразу нескольких значений вы можете использовать метод getArray():

$source = $jinput->getArray(array(
    'var1' => '',
    'var2' => '',
    'var3' => ''
));

Вы также можете задать разные фильтры для каждой из переменных:

$source = $jinput->getArray(array(
    'var1' => 'int',
    'var2' => 'float',
    'var3' => 'word'
));

И можете вкладывать массивы для получения более сложных иерархий значений:

$source = $jinput->getArray(array(
    'jform' => array(
        'title' => 'string',
        'quantity' => 'int',
        'state' => 'int'
    )
));

Получение значений из конкретного суперглобального массива

Класс JInput также поддерживает магический get-метод, который позволяет получить удобный доступ к суперглобальным массивам:

// Получаем доступ к $_POST
 $post = $input->post;

 // Получаем переменные из суперглобальных массивов
 $source = $jinput->get->get('varname', 'default_value', 'filter');
 $source = $jinput->post->get('varname', 'default_value', 'filter');
 $source = $jinput->server->get('varname', 'default_value', 'filter');

Получение данных о файлах

Формат, в котором PHP возвращает данные о файлах, мягко говоря, ужасен. Все становится еще хуже, когда приходится иметь дело с массивом файлов. Класс JInputFiles предоставляет более удобный интерфейс для упрощения работы с файлами, группируя данные по каждому отдельному файлу.

Предположим, что у вас есть следующая форма:

<form action="<?php echo JRoute::_('index.php?option=com_test&task=file.submit'); ?>" enctype="multipart/form-data" method="post">
       <inputtype="file"name="jform[test][]" />
       <inputtype="file"name="jform[test][]" />
       <inputtype="submit"value="submit" />
</form>

PHP передаст эти данные в глобальный массив $_FILES, который будет выглядеть вот так:

Array
(
    [jform] => Array
        (
            [name] => Array
                (
                    [test] => Array
                        (
                            [0] => picture_1.png
                            [1] => picture_2.jpg
                        )                )            [type] => Array
                (
                    [test] => Array
                        (
                            [0] => image/png
                            [1] => image/jpeg
                        )                )            [tmp_name] => Array
                (
                    [test] => Array
                        (
                            [0] => /tmp/phpXoIpSD
                            [1] => /tmp/phpWDE7ye
                        )                )            [error] => Array
                (
                    [test] => Array
                        (
                            [0] => 0
                            [1] => 0
                        )                )            [size] => Array
                (
                    [test] => Array
                        (
                            [0] => 34409
                            [1] => 99529
                        )
                )
        )
)

А теперь попробуем получить эти же данные с помощью JInputFiles:

$files = $jinput->files->get('jform');

Мы получим более понятный и удобный для работы результат:

Array
(
    [test] => Array
        (
            [0] => Array
                (
                    [name] => picture_1.png
                    [type] => image/png
                    [tmp_name] => /tmp/phpXoIpSD
                    [error] => 0
                    [size] => 34409
                )
            [1] => Array
                (
                    [name] => picture_2.jpg
                    [type] => image/jpeg
                    [tmp_name] => /tmp/phpWDE7ye
                    [error] => 0
                    [size] => 99529
                )
        )
)

Установка значений

Для установки значения через JInput вы можете использовать метод set():

$jinput->set('varname', $value);

Первый параметр – это имя переменной, а второй – значение. Наверное, самый популярный пример установки значения в Joomla CMS – это блокировка меню в панели управления:

$jinput->set('hidemainmenu', true);

Dmitry Rekun
Работаю в банковской сфере, а с веб-разработкой (непосредственно с Joomla) столкнулся в 2007 году. Теперь это моё хобби и время от времени вторая работа. Какое-то время вёл свой блог, но решил попробовать работать в команде. И вот c 2012 года я здесь :)