我正在尝试创建一个blade指令,以突出显示将从搜索查询返回的一些单词。
这是我的刀锋指令
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()
{
}
}
我这样叫刀锋战士:
@highlight('ho', 'house')
但是,这个错误一直跟着我:
Missing argument 2 for App\Providers\AppServiceProvider::App\Providers\{closure}()
如何解决呢?
9条答案
按热度按时间jogvjijk1#
对于关联数组,eval()可能是最简单的。但是它的使用被认为是危险的,因为它就像你打开一个洞,一根针来执行代码。在同一时间eval()在运行时执行,它在数据库中存储要执行的代码(缓存[它意味着缓存编译后字节码])。这是额外的开销,因此性能将受到影响。这是一篇关于此主题的不错的文章[未阅读或了解详细信息])https://link.springer.com/chapter/10.1007%2F978-981-10-3935-5_12。
因此
还可以,没什么好谈的()和性能(它已经完成并缓存了,生成的php代码将被反复运行(只要确保该指令返回的php代码不包含eval(),除非有原因)。使用eval()(它将被反复用于不同的请求)将影响性能。(我想谈谈eval(),我认为这些是有用的信息)
我们可以解析数组形式["sometin"=〉"i should be sting",""=〉"",...]。
但是我们不能传递变量。例如:
@directive(["s" => $var])
如果我们使用eval,$var将在指令函数作用域中未定义。(不要忘记,指令只是一种漂亮地生成tempalte的方法,把丑陋的(不是真的丑陋)php代码变成这样的指令。我们把这个漂亮的指令转换成php代码,在最后执行,你在这里所做的就是生成,构建,编写将形成最终PHP页面或文件的表达式)。你可以这样做,即以["s"=〉"$var"]的方式传递变量,这样它就会通过eval,然后在return语句中使用它的例子:
当将生成模板时,这将是
<?php echo $var;?>
;另一种解决方案
(这是容易),以及建议的解析解决方案,是使用json格式将数据传递给您的指令,并只使用json_decode。(我刚刚想到的)
这里有一个例子,我需要这样做:我们的目标是实现自动化
所以我写了这个指令
我们这样使用它:
为什么这个表单可以工作?它是作为一个字符串模板传递的
为了在模板变量中使用,将它们作为字符串传递,如"$var",与我们对eval所做的相同。
对于从[""=〉"",..]格式解析,eval()是最好的选择。记住,这是在模板生成时完成的,模板稍后被缓存,并且不会更新,直到我们再次进行更改。记住,不要在返回中使用eval();指令。(仅当应用程序需要时)
或
你可以根据自己的喜好对它们进行调整,使用str_replace来删除像()......等这样的内容[简而言之,我们自己进行解析。RegEx可能会有帮助。这取决于我们想要实现什么。
以上这些都是解析条目并将它们分离成变量的方法,这些变量用于生成模板,也用于编写return语句。
如果您只想让您的指令从视图范围中获取一个变量数组,该怎么办:
例如
@section('', ["var" => $varValue])
这里我们特别使用多参数解析,然后分别恢复[""=〉..]表达式(这不是重点)。
关键是当你想传递一个数组在你的代码中使用时(视图范围)。你只要照原样使用它就行了。(这可能会让人困惑)。
这将计算为
所以一切都会好的,我举了一个例子,我们使用一个函数,你可以把所有的逻辑,指令只是一种方法,用一种更漂亮的方式写视图,它也允许预览处理和生成,很不错。
qcuzuvrc2#
在叶片模板中:
twh00eeo3#
我一直在寻找这个确切的解决方案,然后决定尝试一些不同的东西后,阅读一切,并最终想出了解决方案,你和我都在寻找。
不需要JSON解决方案、爆炸、关联数组等......除非您以后需要更复杂的功能。
因为Blade只是写出PHP代码供以后解释,所以无论您在@highlight指令中放置了什么,都是字符串格式的PHP代码,这些代码将在以后解释。
操作方法:
创建并注册一个可以在整个应用程序中调用的helper函数,然后在blade指令中使用helper函数。
帮助程序定义:
铲刀指令:
用法(示例):
理解:
这相当于写出:
8ulbf1ek4#
我认为你只能传递一个参数,虽然不太美观,但你可以像这样把参数作为数组传递:
所以你的指令可能是
在此找到:https://laracasts.com/discuss/channels/laravel/how-to-do-this-blade-directive
kuhbmx9i5#
完成这项任务的最好方法正是@Everrett建议的。
我检查了刀片代码,这正是laravel团队必须做的。
如果您浏览
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php
,在compileDd
函数中,您会注意到它们使用$arguments
而不是$expression
,就像vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/
中的所有其他编译函数一样如果你看一下
vendor/symfony/var-dumper/Resources/functions/dump.php
,你会发现Laravel在dd
函数中用...
splat符号处理变量参数。所以你可以写一个指令:* (我把我的自定义函数放在app\helpers中)* 如果你做同样的事情,你需要确保转义反斜杠。
和自定义函数,如:
运行
php artisan view:clear
然后使用指令:
这样做的最好理由是,如果你的函数进化或改变,你只需要修改下划线函数,你不必每次改变代码时都清除视图。
vlf7wbxs6#
我发现了另一种访问Blade指令中的View变量的方法。
我想检查给定的字符串是否作为数组键出现在视图范围内可访问的变量中。
由于刀片指令返回的PHP稍后进行评估,因此可以通过分解变量名来"欺骗"该指令,使其不会试图解析它。
例如:
在本例中,我们将$elementData变量名拆分,以便Blade指令将其视为字符串。当连接后的字符串返回到Blade时,它将被视为变量。
avwztpqn7#
2o7dmzc58#
blade指令函数接收到的值是字符串,因此,必须进行解析以获取值:
刀片
@date($date, 'd-M-Y')
应用程序服务提供程序
6ju8rftf9#
如果你想在一个自定义的blade指令中引用变量,你可能不需要把它们直接传递给这个指令。我通过从一个blade组件中调用blade指令解决了这个问题。Blade组件有局部变量作用域,所以你可以简单地把调用中需要的所有变量传递给blade组件(而不会污染视图作用域)。只要你实际上不需要修改变量或在指令中使用它们作为控制逻辑,这就足够了。