Cai*_*aki 8 php laravel blade laravel-blade laravel-5.3
我正在尝试创建一个刀片指令,以突出显示将从我的搜索查询返回的一些单词.
这是我的刀片指令:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Blade::directive('highlight', function($expression, $string){
$expressionValues = preg_split('/\s+/', $expression);
foreach ($expressionValues as $value) {
$string = str_replace($value, "<b>".$value."</b>", $string);
}
return "<?php echo {$string}; ?>";
});
}
public function register()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我用这样的方式调用刀片:
@highlight('ho', 'house')
Run Code Online (Sandbox Code Playgroud)
但是,这个错误跟随着我:
Missing argument 2 for App\Providers\AppServiceProvider::App\Providers\{closure}()
Run Code Online (Sandbox Code Playgroud)
怎么解决?
小智 8
Blade::directive('custom', function ($expression) {
eval("\$params = [$expression];");
list($param1, $param2, $param3) = $params;
// Great coding stuff here
});
Run Code Online (Sandbox Code Playgroud)
在刀片模板中:
@custom('param1', 'param2', 'param3')
Run Code Online (Sandbox Code Playgroud)
我一直在寻找这个确切的解决方案,然后在阅读完所有内容后决定尝试不同的方法,最终得出了你和我都在寻找的解决方案。
不需要 JSON 解决方法、分解、关联数组等...除非您希望以后使用该功能来实现更复杂的功能。
因为 Blade 只是写出稍后解释的 PHP 代码,所以您在 @highlight 指令中放入的内容都是字符串格式的确切 PHP 代码,稍后将被解释。
该怎么办:
创建并注册一个可以在整个应用程序中调用的辅助函数。然后在 Blade 指令中使用辅助函数。
助手定义:
if(!function_exists('highlight')){
function highlight($expression, $string){
$expressionValues = preg_split('/\s+/', $expression);
foreach ($expressionValues as $value) {
$string = str_replace($value, "<b>".$value."</b>", $string);
}
return $string;
}
}
Run Code Online (Sandbox Code Playgroud)
刀片指令:
Blade::directive('highlight', function ($passedDirectiveString){
return "<?php echo highlight($passedDirectiveString);?>";
});
Run Code Online (Sandbox Code Playgroud)
用法(示例):
<div>
@highlight('ho', 'house')
</div>
Run Code Online (Sandbox Code Playgroud)
理解:
这相当于写出:
<div>
{! highlight('ho', 'house') !}
</div>
Run Code Online (Sandbox Code Playgroud)
对于关联数组,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 ..";
});
Run Code Online (Sandbox Code Playgroud)
没关系 关于eval()和性能没有什么可谈的(已经完成并缓存了,生成的php代码将一遍又一遍地运行(只要确保指令返回的php代码不包含eval(), ,除非有原因)直接使用eval()(将反复用于不同的请求)会影响性能(我想谈谈eval(),我认为这些都是有用的信息)
因为我们可以解析数组形式[“ sometin” =>“我应该被刺”,“” =>“”,...]。
eval("\$array = $expression;");
// then we can do what we want with $array
Run Code Online (Sandbox Code Playgroud)
但是我们不能传递变量。例如: @directive(["s" => $var])
如果我们使用eval,则$ var将在指令函数范围内未定义。(别忘了该指令只是一种漂亮地生成tempalte的方法,并将丑陋的(而不是真正丑陋的)php代码转换成这样的指令。实际上,相反,我们正在将漂亮的指令转换为php代码,最后执行。您在这里要做的就是生成,构建,编写将构成最终php页面或文件的表达式。)
您可以做的是以这种方式传递变量[“ s” =>“ $ var”],这样它将通过eval传递。然后在您的return语句中,使用它作为示例:
return "<?php echo ".$array['s'].";?>";
Run Code Online (Sandbox Code Playgroud)
当模板生成的时候<?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()
{
}
}
Run Code Online (Sandbox Code Playgroud)
这是我需要这样做的一个示例:目标是使它自动化
@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 ...
Run Code Online (Sandbox Code Playgroud)
所以我写了这个指令:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
我们这样使用它:
@varSet({
"logo": "logo",
"width": 78,
"height": 22
})// hi my cool directive. that's slick.
Run Code Online (Sandbox Code Playgroud)
为什么这种形式有效?它像这样作为字符串模板传递
"""
{\n
"logo": "logo",\n
"width": 78,\n
"height": 22\n
}
"""
Run Code Online (Sandbox Code Playgroud)
对于在模板变量中使用,请将其作为字符串传递,例如“ $ var”,与我们对eval所做的相同。
对于从[“” =>“”进行解析,..]格式可能是eval()是最佳选择。请记住,这是在模板生成时完成的,该模板稍后会缓存,并且不会更新,直到我们再次进行更改。并记住不要在return中使用eval();指令说明。(仅在您的应用程序需要时)
仅用于多个参数,而不用于数组: 像这样的函数将完成此工作:
public static function parseMultipleArgs($expression)
{
return collect(explode(',', $expression))->map(function ($item) {
return trim($item);
});
}
Run Code Online (Sandbox Code Playgroud)
要么
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;
}
Run Code Online (Sandbox Code Playgroud)
然后您可以根据需要对其进行调整,使用str_replace删除()... etc之类的内容[总之,我们进行自己的解析。正则表达式可能会有所帮助。并取决于我们要实现的目标。
以上所有方法都是解析条目并将其分成用于生成模板的变量的方法。因此,使您的退货声明。
像 @section('', ["var" => $varValue])
好吧,这里我们特别使用多参数解析,然后分别恢复[“” => ..]表达式(这里不是重点)。
关键是当您想要传递要在代码中使用的数组(查看范围)时。您可以按原样使用它。(这可能会造成混淆)。
例如:
Blade::directive("do", function ($expr) {
return "<?php someFunctionFromMyGlobalOrViewScopThatTakeArrayAsParameter($expr); ?>
});
Run Code Online (Sandbox Code Playgroud)
这将评估为
<?php someFunctionFromMyGlobalOrViewScopThatTakeArrayAsParameter(["name" => $user->name, .......]); ?>
Run Code Online (Sandbox Code Playgroud)
因此,一切都会正常进行。我举了一个例子,我们使用一个函数,可以放所有逻辑。指令只是一种以更优美的方式编写视图的方式。它还允许预览处理和生成。安静点
我认为你只能传递一个参数。它并不漂亮,但您可以将参数作为数组传递,如下所示:
@highlight(['expression' => 'ho', 'string' => 'house'])
Run Code Online (Sandbox Code Playgroud)
所以你的指令可能是
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Blade::directive('highlight', function($array){
$expressionValues = preg_split('/\s+/', $array['expression']);
foreach ($expressionValues as $value) {
$array['string'] = str_replace($value, "<b>".$value."</b>", $array['string']);
}
return "<?php echo {$array['string']}; ?>";
});
}
public function register()
{
}
}
Run Code Online (Sandbox Code Playgroud)
在这里找到它:https ://laracasts.com/discuss/channels/laravel/how-to-do-this-blade-directive
| 归档时间: |
|
| 查看次数: |
5898 次 |
| 最近记录: |