Best Practices for Custom Helpers in Laravel 5

后端 未结 20 2027
暖寄归人
暖寄归人 2020-11-22 06:40

I would like to create helper functions to avoid repeating code between views in Laravel 5:

view.blade.php

Foo Formated text: {{ fo

20条回答
  •  悲&欢浪女
    2020-11-22 07:30

    Since OP asked for best practices, I think we're still missing some good advices here.

    A single helpers.php file is far from a good practice. Firstly because you mix a lot of different kind of functions, so you're against the good coding principles. Moreover, this could hurt not only the code documentation but also the code metrics like Cyclomatic Complexity, Maintainability Index and Halstead Volume. The more functions you have the more it gets worse.

    Code documentation would be Ok using tools like phpDocumentor, but using Sami it won't render procedural files. Laravel API documentation is such a case - there's no helper functions documentation: https://laravel.com/api/5.4

    Code metrics can be analyzed with tools like PhpMetrics. Using PhpMetrics version 1.x to analyze Laravel 5.4 framework code will give you very bad CC/MI/HV metrics for both src/Illuminate/Foundation/helpers.php and src/Illuminate/Support/helpers.php files.

    Multiple contextual helper files (eg. string_helpers.php, array_helpers.php, etc.) would certainly improve those bad metrics resulting in an easier code to mantain. Depending on the code documentation generator used this would be good enough.

    It can be further improved by using helper classes with static methods so they can be contextualized using namespaces. Just like how Laravel already does with Illuminate\Support\Str and Illuminate\Support\Arr classes. This improves both code metrics/organization and documentation. Class aliases could be used to make them easier to use.

    Structuring with classes makes the code organization and documentation better but on the other hand we end up loosing those great short and easy to remember global functions. We can further improve that approach by creating function aliases to those static classes methods. This can be done either manually or dynamically.

    Laravel internally use the first approach by declaring functions in the procedural helper files that maps to the static classes methods. This might be not the ideal thing as you need to redeclare all the stuff (docblocks/arguments).
    I personally use a dynamic approach with a HelperServiceProvider class that create those functions in the execution time:

     'App\Support\Helpers\StringHelper::uppercase',
            'lowercase' => 'App\Support\Helpers\StringHelper::lowercase',
        ];
    
        /**
         * Bootstrap the application helpers.
         *
         * @return void
         */
        public function boot()
        {
            foreach ($this->helpers as $alias => $method) {
                if (!function_exists($alias)) {
                    eval("function {$alias}(...\$args) { return {$method}(...\$args); }");
                }
            }
        }
    
        /**
         * Register the service provider.
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }
    

    One can say this is over engineering but I don't think so. It works pretty well and contrary to what might be expected it does not cost relevant execution time at least when using PHP 7.x.

提交回复
热议问题