Статьи

Совет: удобство взлома для передачи данных в представления

В архитектурах на основе MVC работа с шаблонизаторами является неизбежной частью рутины разработки. Обычно это происходит так: мы подготавливаем и передаем данные в представление. По нашему мнению, мы печатаем их на основе нашего макета.

Вот основной пример того, как это работает с использованием Twig .

<?php

// Twig initialization

// Preparing data

$user     = 'user data';
$posts    = 'posts';
$comments = 'comments';

$twig->render('author.page', [

    'user'     => $user,
    'posts'    => $posts,
    'comments' => $comments,

]);

// ...

Однако бывают случаи, когда число переменных может быть намного больше, чем это: десять или более. В этом случае у нас будет большой список переменных (в виде ассоциативного массива), передаваемых в соответствующий шаблон. Это становится грязным и нечитаемым быстро. Если бы только был способ просто перечислить то, что нам нужно, по имени, а PHP позаботиться обо всем остальном за нас. Ну … есть!

В этом посте мы поговорим о хитрости для передачи определенных переменных в представление несколько более удобным способом: мы можем использовать встроенную в PHP функцию compact () для ручной выборки нужных нам данных, ссылаясь на переменные по имени:

 <?php

// Twig initialization

// Preparing data

$user     = 'user data';
$posts    = 'posts';
$comments = 'comments';

$twig->render('author.page', compact('user', 'posts'));

// ...

compact()

Иногда даже удобнее указывать переменные, которые нам не нужны, вместо тех, которые нам нужны. Поскольку в PHP нет встроенного решения для сжатия всех переменных (в пределах текущей области видимости), за исключением нескольких из них, мы должны сделать это в три этапа.

Сначала нам нужно получить все переменные в области видимости контроллера с помощью get_defined_vars()

 <?php
// ...
$variables = get_defined_vars();
// ...

Затем мы отфильтровываем нежелательные имена переменных от требуемых, используя PHP-функцию array_diff .

array_diffодним или несколькими массивами и возвращает записи в первом массиве , которых нет ни в одном из других массивов.

 <?php
// ...
$variables = get_defined_vars();
$including = array_diff(array_keys($variables), ['user', 'posts', 'comments']);
// ...

Наконец, мы можем извлечь нужные переменные (перечисленные в $including$variablesarray_intersect_key() .

array_intersect_key()первого массива, ключи которого существуют во всех других массивах.

Обратите внимание: поскольку array_intersect_key()$includingarray_flip () :

 <?php
// ...
$variables = get_defined_vars();
$including = array_diff(array_keys($variables), ['user', 'posts', 'comments']);

$vars = array_intersect_key($variables, array_flip($including));
// ...

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

 <?php

//Helpers.php

// ...

if (!function_exists('only_compact')) {

    function only_compact($values, $keys) {
        $keys = array_diff(array_keys($values), $keys);
        return array_intersect_key($values, array_flip($keys));

}

И вот как это облегчит жизнь:

 <?php

// Twig initialization...

// Preparing data

$user          = 'user data';
$posts         = 'posts';
$comments      = 'comments';
$anotherOne    = 'some value';
$yetAnotherOne = 0;
$andAnotherOne = 0;
$counter       = 0;
$test_1        = 1;
$test_2        = 2;
$test_3        = 3;
$test_4        = 4;
$test_5        = 5;
$test_6        = 6;

// Even more variables ...

$twig->render('author.page', only_compact(get_defined_vars(), ['counter', 'twig']));
);

// ...

В результате мы получаем массив переменных со всеми исключенными нежелательными переменными.

Чтобы использовать вспомогательный файл, мы можем добавить его в filesautoloadcomposer.json

 // ...

    "autoload":{
        "files": [
            "helpers.php"
        ]
    }

// ...

Поскольку мы используем встроенные функции PHP, влияние на производительность не заметно. Ниже приведен результат быстрого теста профиля, проведенного с Blackfire , до и после использования вышеуказанных методов:

Без использования функций:

Без функций

С использованием функций:

с функциями

Как видите, результаты обоих профилей практически одинаковы.

Надеюсь, этот трюк спасет вас от набора текста!

Есть еще какие-нибудь советы, которые вы можете использовать в отношении шаблонов и просмотра эффективности? Дайте нам знать!