В архитектурах на основе 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
$variables
array_intersect_key()
.
array_intersect_key()
первого массива, ключи которого существуют во всех других массивах.
Обратите внимание: поскольку array_intersect_key()
$including
array_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']));
);
// ...
В результате мы получаем массив переменных со всеми исключенными нежелательными переменными.
Чтобы использовать вспомогательный файл, мы можем добавить его в files
autoload
composer.json
// ...
"autoload":{
"files": [
"helpers.php"
]
}
// ...
Поскольку мы используем встроенные функции PHP, влияние на производительность не заметно. Ниже приведен результат быстрого теста профиля, проведенного с Blackfire , до и после использования вышеуказанных методов:
Без использования функций:
С использованием функций:
Как видите, результаты обоих профилей практически одинаковы.
Надеюсь, этот трюк спасет вас от набора текста!
Есть еще какие-нибудь советы, которые вы можете использовать в отношении шаблонов и просмотра эффективности? Дайте нам знать!