How to use class from blade template?

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

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



        
相关标签:
2条回答
  • 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
    <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).

    0 讨论(0)
  • 2021-01-14 15:38

    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;
        }
    
    }
    

    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"
        ]
    }
    

    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
    

    it refreshes the autoload cache.

    Step 4

    You can now use your class from anywhere including blade

    <tr class="{{ Helper::applyClass("user") }}">
    

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

    0 讨论(0)
提交回复
热议问题