如何使用刀片模板中的类?

6 laravel laravel-5

Helper用路径创建了类App\Http\Helpers\

<?php

namespace App\Http\Helpers;

class Helper 
{
    public static function applyClass($user) {
        return "new";
    }

}
Run Code Online (Sandbox Code Playgroud)

然后我app.php在部分注册了它aliases

'Helper' =>   App\Http\Helpers\Helper::class
Run Code Online (Sandbox Code Playgroud)

当我尝试从刀片调用静态方法时:

<tr class="{{ \Helper::applyClass($user) }}">
<tr class="{{ Helper::applyClass($user) }}">
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

Class 'Helper' not found
Run Code Online (Sandbox Code Playgroud)

Nam*_*hek 17

这不是门面的工作方式。需要扩展自定义门面Illuminate\Support\Facades\Facade,基本上只需要自定义门面来实现protected static function getFacadeAccessor()。此方法应返回应该由外观解析的名称(或类或接口)。

外观允许您以static静态方式调用实例方法(即非方法)。这是有效的,因为门面知道如何将对静态方法的调用重定向到门面后面的实例。这是通过实现完成的__callStatic($method, $args),它只是将静态方法调用重定向到名称由 返回的实现getFacadeAccessor()

假设您helper在服务容器中以该名称注册了一个服务。然后,您可以getColor()使用app('helper')->getColor()或对其执行一个方法app()->make('helper')->getColor()

通过调用的外观通过从方法将其作为字符串返回Helper来解析您的外观,然后您可以使用.helpergetFacadeAccessor()Helper::getColor()


就您而言,您现在有几个选择:

1) 使用带有静态方法的类:

与您已经做过的类似,您可以使用静态方法定义一个类。然后,您可以使用完全限定的类名 (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>
Run Code Online (Sandbox Code Playgroud)

2) 使用带有外观的非静态类:

您可以将与上述类似的类与非静态方法一起使用,并为其添加外观:

// 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>
Run Code Online (Sandbox Code Playgroud)

3) 使用全局非类帮助文件:

您还可以定义一个基本的 PHP 文件,其中包含一些全局注册的辅助函数。这些函数不是类方法,因此不需要使用类前缀调用:

// 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>
Run Code Online (Sandbox Code Playgroud)

4)使用类和服务注入:

还有一个不错的选择是使用服务容器将服务注入到 Blade 模板中。Laravel 提供了一个 Blade 指令来调用@inject($var, $fqdn)它。

// 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>
Run Code Online (Sandbox Code Playgroud)

我希望代码不言自明。故意省略文件的命名空间,当然您应该根据目录使用命名空间(符合 PSR-4)。

如果您不需要任何依赖项并且基本上只需要静态访问某些东西,我个人更喜欢全局助手(选项 3)。

  • 这就是答案,很好的解释,应该蒙着眼睛接受。我错过了双重赞成票。 (2认同)

Udo*_* E. 6

You can achieve this in a straight forward way by following these steps.

Step 1

Create your class file in your desired path (example: app/Helpers/Helper.php) and define the class

<?php

class Helper 
{
    public static function applyClass($user) {
        return "call from helper to " . $user;
    }

}
Run Code Online (Sandbox Code Playgroud)

Step 2

Modify composer.json file by adding your file within the entry of the autoload key

"autoload": {
    "prs-4": {
        "App\\": "app/"
    },
    "files": [
        "app/Helpers/Helper.php"
    ]
}
Run Code Online (Sandbox Code Playgroud)

Note that you are not changing anything apart from including this entry: "files": ["app/Helpers/Helper.php"]. Save the file.

Step 3

Run this command from your root directory:

composer dump-autoload
Run Code Online (Sandbox Code Playgroud)

it refreshes the autoload cache.

Step 4

You can now use your class from anywhere including blade

<tr class="{{ Helper::applyClass("user") }}">
Run Code Online (Sandbox Code Playgroud)

This way, you can also create global functions as well.