Для ассоциативных массивов проще всего использовать eval(). Но его использование рекламируется как опасное, потому что это как открытие дыры, иглы для выполнения кода. В то же время eval() выполняется во время выполнения, он сохраняет код для выполнения в базе данных (кэширование [ну, это означает, что он кэширует скомпилированный байт-код]). Это дополнительные накладные расходы, поэтому производительность пострадает. Вот хорошая статья по теме [не читал и не вникал в детали]) https://link.springer.com/chapter/10.1007%2F978-981-10-3935-5_12.
Возможно, я вас понял! нет никакой разницы в производительности сервера, обслуживающего производительность, потому что представления кэшируются и генерируются только тогда, когда вы их меняете. Директивы транслируются в php-код и в другом процессе кэшируются. (вы можете найти сгенерированное представление в storage/framework/views)
Итак, для
Blade::directive('custom', function ($expression) {
eval("\$myarray = [$expression];");
// do something with $myarray
return "<?php echo ..";
});
Все в порядке. Не о чем говорить про eval() и производительность (это делается и кешируется, а сгенерированный php-код — это тот, который будет выполняться снова и снова (просто убедитесь, что возвращенный php-код директивой не содержит eval() , если нет причины. Непосредственное использование eval() (которое будет использоваться для разных запросов снова и снова) повлияет на производительность. (Я хотел поговорить о eval(), я думаю, что это полезная информация)
так как мы можем анализировать форму массива ["sometin" => "я должен быть жалом", "" => "", ...].
eval("\$array = $expression;");
// then we can do what we want with $array
Однако мы не можем передавать переменные. пример: @directive(["s" => $var])
если мы используем eval, $var не будет определено в области действия функции директивы. (не забывайте, что директива — это всего лишь способ красиво сгенерировать tempalte и превратить уродливый (не совсем уродливый) php-код в такую директиву. На самом деле это наоборот, мы превращаем красивую директиву в php-код, который будет выполняется в конце. И все, что вы здесь делаете, это генерируете, строите, пишете выражение, которое сформирует окончательные php-страницы или файлы.)
Вместо этого вы можете передать переменную таким образом ["s" => "$var"] , чтобы она прошла через eval. А затем в своем операторе возврата используйте его пример:
return "<?php echo ".$array['s'].";?>";
когда шаблон будет сгенерирован, это будет <?php echo $var;?>
;
Помните, если вы решите использовать eval, никогда не используйте его в возвращаемой строке! или, возможно, вы захотите в некоторых случаях.
Другое решение
(что просто) наряду с предлагаемыми решениями синтаксического анализа заключается в использовании формата json для передачи данных в вашу директиву и просто использовании json_decode. . (до меня только что дошло)
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Blade::directive('highlight', function($json_expression){
$myArray = json_decode($json_expression)
// do something with the array
});
}
public function register()
{
}
}
Вот пример, где мне нужно было это сделать: цель состоит в том, чтобы автоматизировать это
@php
$logo = !empty($logo) ? $logo : 'logo';
$width = !empty($width) ? $width : 'logo';
//... // wait i will not always keep doing that ! h h
@endphp // imaging we do that for all different number of view components ...
и поэтому я написал эту директиву:
public function boot()
{
Blade::directive('varSet', function ($expr) {
$array = json_decode($expr, true);
$p = '<?php ';
foreach ($array as $key => $val) {
if (is_string($val)) {
$p .= "\$$key = isset(\$$key) && !empty(\$$key) ? \$$key : '$val'; ";
} else {
$p .= "\$$key = isset(\$$key) && !empty(\$$key) ? \$$key : $val; ";
}
}
$p .= '?>';
return $p;
});
}
Мы используем это так:
@varSet({
"logo": "logo",
"width": 78,
"height": 22
})// hi my cool directive. that's slick.
Почему эта форма работает? он передается как строковый шаблон, подобный этому
"""
{\n
"logo": "logo",\n
"width": 78,\n
"height": 22\n
}
"""
Для использования в переменной шаблона передайте их как строку, подобную этой "$var", так же, как мы сделали с eval.
Для разбора из ["" => "", ..] формат может быть eval() - лучший выбор. Помните, что это делается при создании шаблонов, которые позже кэшируются и не обновляются, пока мы снова не внесем изменения. И не забудьте не использовать eval() в return ; директивная инструкция. (только если это нужно вашему приложению)
только для нескольких аргументов, а не для массива: подобная функция выполнит эту работу:
public static function parseMultipleArgs($expression)
{
return collect(explode(',', $expression))->map(function ($item) {
return trim($item);
});
}
or
public static function parseMultipleArgs($expression)
{
$ar = explode(',', $expression);
$l = len($ar);
if($l == 1) return $ar[0];
for($i = 0; $i < $l; $i++){$ar[$i] = trim($ar[$i])}
return $ar;
}
и вы можете настроить их по своему усмотрению, используя str_replace для удаления таких вещей, как () ... и т. д. [короче говоря, мы тренируем свой собственный синтаксический анализ. RegEx может быть полезным. И зависит от того, чего мы хотим достичь.
Все вышеперечисленное — это способ анализа записей и разделения их на переменные, которые вы используете для создания шаблона. И так для того, чтобы сделать заявление о возврате.
ЧТО ЕСЛИ ВСЕ, ЧТО ВЫ ХОТИТЕ, ЭТО ПОЛУЧИТЬ, ЧТОБЫ ВАША ДИРЕКТИВА ВЗЯЛА МАССИВ С ПЕРЕМЕННЫМИ ИЗ ОБЛАСТИ ПРЕДСТАВЛЕНИЯ:
как в @section('', ["var" => $varValue])
Ну тут конкретно мы используем многоаргументный разбор, потом восстанавливаем выражение ["" => ..] отдельно (и тут не в этом дело).
Дело в том, что вы хотите передать массив, который будет использоваться в вашем коде (область просмотра). Вы просто используете его как есть. (можно запутать).
пример:
Blade::directive("do", function ($expr) {
return "<?php someFunctionFromMyGlobalOrViewScopThatTakeArrayAsParameter($expr); ?>
});
Это будет оцениваться как
<?php someFunctionFromMyGlobalOrViewScopThatTakeArrayAsParameter(["name" => $user->name, .......]); ?>
А так все будет работать нормально. Я взял пример, где мы используем функцию, вы можете поставить всю логику. Директивы — это просто способ написать представление более красивым способом. Также это позволяет выполнять предварительную обработку и генерацию. Тихо приятно.
person
Mohamed Allal
schedule
09.11.2018