How to use class from blade template?

后端 未结 2 1031
逝去的感伤
逝去的感伤 2021-01-14 15:15

I have created class Helper with path App\\Http\\Helpers\\:



        
2条回答
  •  猫巷女王i
    2021-01-14 15:26

    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
    
    ...

    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
    
    ...

    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
    
    ...

    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)
    
    
    ...

    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).

提交回复
热议问题