如何使用刀片模板中的类? [英] How to use class from blade template?
问题描述
我创建了类 Helper
,其路径为 App \ Http \ Helpers \
:
<?php命名空间App \ Http \ Helpers;类助手{公共静态函数applyClass($ user){返回新";}}
然后我将其注册在 alias
部分的 app.php
中:
'Helper'=>App \ Http \ Helpers \ Helper :: class
当我尝试从Blade调用静态方法时:
< tr class ="{{\ Helper :: applyClass($ user)}}">< tr class ="{{Helper :: applyClass($ user)}}">
我得到一个错误:
找不到 类'Helper'
外墙不是这样工作的.需要自定义外观来扩展 Illuminate \ Support \ Facades \ Facade
,这基本上只需要自定义外观即可实现受保护的静态函数getFacadeAccessor()
.此方法应返回应该由外观解析的名称(或类或接口).
Facade允许您以静态方式调用实例方法(即非 static
方法).之所以可行,是因为Facade知道如何将对静态方法的调用重定向到Facade后面的实例.这是通过实现 __ callStatic($ method,$ args)
来完成的,该方法只是将静态方法调用重定向到由 getFacadeAccessor()
返回名称的实现./p>
想象一下,您已经在服务容器中以 helper
名称注册了一项服务.然后,您可以使用 app('helper')-> getColor()
或 app()-> make()在其上执行方法
. getColor()
'helper')-> getColor()
使用名为 Helper
的外观,通过从 getFacadeAccessor()
方法将其作为字符串返回来解析您的 helper
,然后可以执行使用 Helper :: getColor()
进行相同的操作.
就您而言,您现在有一些选择:
1)将类与静态方法一起使用:
类似于您已经做过的事情,您可以使用静态方法定义一个类.然后,您可以使用标准类名(FQCN)从刀片视图中静态调用这些方法:
//app/Helpers/Helper.php类助手{公共静态函数getColor():字符串{返回蓝色";}}//资源/视图/some/page.blade.php< div style ="颜色:{{\ App \ Helpers \ Helper :: getColor()}}">...</div>
2)使用带有外墙的非静态类:
您可以将上述类似的类与非静态方法一起使用,并为其添加外观:
//app/Helpers/Helper.php类助手{公共函数getColor():字符串{返回蓝色";}}//app/Facades/Helper.phpclass Helper扩展\ Illuminate \ Support \ Facades \ Facade{公共函数getFacadeAccessor(){返回\ App \ Helpers \ Helper :: class;}}//config/app.php->'别名'数组[//...其他外墙...'Helper'=>\ App \ Facades \ Helper :: class,]//资源/视图/some/page.blade.php< div style ="颜色:{{\ Helper :: getColor()}}">...</div>
3)使用全局非类帮助器文件:
您还可以定义一个基本的PHP文件,其中包含一些在全球范围内注册的帮助程序功能.这些函数不是类方法,因此不需要使用类前缀来调用:
//app/Helpers/color_utils.php如果(!function_exists('get_color')){函数get_color(){返回蓝色";}}//app/Providers/HelperServiceProvider.phpHelperServiceProvider类扩展\ Illuminate \ Support \ ServiceProvider{公共函数register():无效{$ filenames = glob(app_path('Helpers/*.php'));if($ filenames!== false&& is_iterable($ filenames)){foreach($ filenames as $ filename){require_once $文件名;}}}}//config/app.php->提供者"数组[//...其他提供者...\ App \ Providers \ HelperServiceProvider :: class,]//资源/视图/some/page.blade.php< div样式="颜色:{{get_color()}}">...</div>
4)使用类和服务注入:
另一个不错的选择是使用服务容器将服务注入Blade模板.Laravel为此提供了一个名为 @inject($ var,$ fqdn)
的Blade指令.
//app/Helpers/Helper.php类助手{公共静态函数getColor():字符串{返回蓝色";}}//资源/视图/some/page.blade.php@inject('helper',\ App \ Helpers \ Helper :: class)< div样式="颜色:{{$ helper-> getColor()}}"...</div>
我希望代码能说明一切.这些文件的命名空间是有意省略的,当然,您应该根据目录(符合PSR-4)使用命名空间.
如果您不需要任何依赖关系,并且基本上只需要静态访问某些内容,那么我个人更喜欢全局助手(选项3).
I have created class Helper
with path App\Http\Helpers\
:
<?php
namespace App\Http\Helpers;
class Helper
{
public static function applyClass($user) {
return "new";
}
}
Then I have registered it in app.php
in section aliases
:
'Helper' => App\Http\Helpers\Helper::class
When I tried to call static method from blade:
<tr class="{{ \Helper::applyClass($user) }}">
<tr class="{{ Helper::applyClass($user) }}">
I get an error:
Class 'Helper' not found
This is not how facades work. A custom facade is required to extend Illuminate\Support\Facades\Facade
, which basically only requires the custom facade to implement protected static function getFacadeAccessor()
. This method should return the name (or a class or an interface) which is supposed to be resolved by the facade.
A facade allows you to call instance methods (i.e. non-static
methods) in a static way. This works because facades know how to redirect calls to static methods to the instance behind the facade. This is done by implementing __callStatic($method, $args)
, which simply redirects the static method call to the implementation of which the name is returned by getFacadeAccessor()
.
Imagine you have a service registered under the name helper
in the service container. You could then execute a method getColor()
on it using app('helper')->getColor()
or app()->make('helper')->getColor()
.
With a facade called Helper
which resolves your helper
by returning it as string from the getFacadeAccessor()
method, you can then perform the same action using Helper::getColor()
.
In your case, you have a few options now:
1) Using a class with static methods:
Similarly to what you already did, you can define a class with static methods. You then call these methods statically from your blade view by using the fully qualified class name (FQCN):
// app/Helpers/Helper.php
class Helper
{
public static function getColor(): string
{
return 'blue';
}
}
// resources/views/some/page.blade.php
<div style="color:{{ \App\Helpers\Helper::getColor() }}"> ... </div>
2) Using a non-static class with a facade:
You can use a similar class as above with non-static methods and add a facade for it:
// app/Helpers/Helper.php
class Helper
{
public function getColor(): string
{
return 'blue';
}
}
// app/Facades/Helper.php
class Helper extends \Illuminate\Support\Facades\Facade
{
public function getFacadeAccessor()
{
return \App\Helpers\Helper::class;
}
}
// config/app.php -> 'aliases' array
[
// ... other facades ...
'Helper' => \App\Facades\Helper::class,
]
// resources/views/some/page.blade.php
<div style="color:{{ \Helper::getColor() }}"> ... </div>
3) Using a global non-class helper file:
You can also define a basic PHP file containing some helper functions, which are registered globally. These functions are not class methods and do therefore not require being called with a class prefix:
// app/Helpers/color_utils.php
if (!function_exists('get_color')) {
function get_color()
{
return 'blue';
}
}
// app/Providers/HelperServiceProvider.php
class HelperServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function register(): void
{
$filenames = glob(app_path('Helpers/*.php'));
if ($filenames !== false && is_iterable($filenames)) {
foreach ($filenames as $filename) {
require_once $filename;
}
}
}
}
// config/app.php -> 'providers' array
[
// ... other providers ...
\App\Providers\HelperServiceProvider::class,
]
// resources/views/some/page.blade.php
<div style="color:{{ get_color() }}"> ... </div>
4) Using a class and service injection:
Also a nice option is to inject a service into a Blade template using the service container. Laravel provides a Blade directive called @inject($var, $fqdn)
for it.
// app/Helpers/Helper.php
class Helper
{
public static function getColor(): string
{
return 'blue';
}
}
// resources/views/some/page.blade.php
@inject('helper', \App\Helpers\Helper::class)
<div style="color:{{ $helper->getColor() }}"> ... </div>
I hope the code speaks for itself. Namespaces of the files are omitted on purpose, of course you should use the namespaces according to the directories (PSR-4 compliant).
If you don't need any dependencies and you basically only need static access to something, I personally prefer global helpers (option 3).
这篇关于如何使用刀片模板中的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!