【问题标题】:如何在 Laravel 中创建自定义辅助函数
【发布时间】:2015-04-02 03:25:01
【问题描述】:

我想创建辅助函数以避免在 Laravel 中的视图之间重复代码。例如:

view.blade.php

<p>Foo Formated text: {{ fooFormatText($text) }}</p>

它们基本上是文本格式化功能。我应该如何定义像fooFormatText()这样的全局可用的辅助函数?

【问题讨论】:

    标签: php laravel laravel-helper


    【解决方案1】:

    在您的应用文件夹中创建一个helpers.php 文件并使用composer 加载它:

    "autoload": {
        "classmap": [
            ...
        ],
        "psr-4": {
            "App\\": "app/"
        },
        "files": [
            "app/helpers.php" // <---- ADD THIS
        ]
    },
    

    将其添加到您的 composer.json 文件后,运行以下命令:

    composer dump-autoload
    

    如果您不喜欢将 helpers.php 文件保存在 app 目录中(因为它不是 PSR-4 命名空间的类文件),您可以执行 laravel.com 网站所做的事情:存储 helpers.php in the bootstrap directory。记得在你的composer.json 文件中设置它:

    "files": [
        "bootstrap/helpers.php"
    ]
    

    【讨论】:

    • 新手提示:更改 composer.json 后使用此命令。作曲家转储自动加载
    • @AllfaridMoralesGarcía 或者只是“一个有用的提示,因为答案并没有明确说明您需要在之后执行此操作”。
    • 我赞成帮助函数以使编写视图更容易,但我讨厌在其他答案中引用了多少这个答案。不要误会我的意思,这是一个很好的答案,而且是正确的,我只是担心人们会滥用它并再次开始编写大量编写不良、组织不良的功能性 PHP。
    • 我不明白这种方法。 Composer 应该是一个包含库的工具:没有它,Laravel 可以很好地工作,而没有 Laravel 的 Composer。这个建议告诉我们在我们的应用程序中创建一个文件,离开我们的应用程序,转到 Composer,告诉 Composer 回到我们的应用程序并包含一个文件。 Laravel 清楚地处理了文件的包含,对吧?为什么我们要放弃 Laravel 的原生实现并使用这个外部工具为我们包含一个文件,从而将我们的应用程序更多地耦合到 Composer?是懒惰,还是我错过了什么?
    • Laravel 使用 composer 的自动加载器来知道在哪里包含它所依赖的所有库和文件。这在 bootstrap/autoload.php 中引用。阅读该文件中的注释。方法是将文件的引用添加到 composer.json 中,然后“dump autoload”,它会重新生成 composer 的自动加载器,以便 Laravel 可以找到它。使用 Composer 的“文件”集合是添加库或一次性函数文件的好方法,这些文件没有整齐地包装在 composer 包中。很高兴为所有“顺便说一句我必须包含这个奇怪的文件”情况提供一个地方。
    【解决方案2】:

    Laravel 5 中的自定义类,简单的方法

    这个答案适用于 Laravel 中的 general 自定义类。如需更具体的 Blade 答案,请参阅 Custom Blade Directives in Laravel 5

    第 1 步:创建您的 Helpers(或其他自定义类)文件并为其提供匹配的命名空间。编写你的类和方法:

    <?php // Code within app\Helpers\Helper.php
    
    namespace App\Helpers;
    
    class Helper
    {
        public static function shout(string $string)
        {
            return strtoupper($string);
        }
    }
    

    第 2 步:创建别名:

    <?php // Code within config/app.php
    
        'aliases' => [
         ...
            'Helper' => App\Helpers\Helper::class,
         ...
    

    第 3 步:在项目根目录中运行 composer dump-autoload

    第 4 步:在 Blade 模板中使用它:

    <!-- Code within resources/views/template.blade.php -->
    
    {!! Helper::shout('this is how to use autoloading correctly!!') !!}
    

    加分:在你的 Laravel 应用中的任何地方使用这个类:

    <?php // Code within app/Http/Controllers/SomeController.php
    
    namespace App\Http\Controllers;
    
    use Helper;
    
    class SomeController extends Controller
    {
    
        public function __construct()
        {
            Helper::shout('now i\'m using my helper class in a controller!!');
        }
        ...
    

    来源:http://www.php-fig.org/psr/psr-4/

    为什么有效:https://github.com/laravel/framework/blob/master/src/Illuminate/Support/ClassLoader.php

    自动加载的来源: http://php.net/manual/en/language.oop5.autoload.php

    【讨论】:

    • 需要明确的是,这个答案实际上并不涉及助手,它们是全局命名空间函数。相反,它鼓励将助手转换为类方法。这通常是最好的方法,但实际上并不能回答这里提出的问题,这就是为什么其他答案相比之下如此复杂的原因。
    • 函数助手意味着它在 Blade 中也可用。你如何使这个函数在刀片中可用?你不能在刀片中调用 Helper::prettyJason(parameters)。
    • @MaXi32 你可以在app/config.phpaliases 数组下添加类:'Helper' =&gt; App\Helpers\Helper::class, 然后你就可以在刀片中调用Helper::prettyJson(); 就好了。
    • 是的,我翻遍了框架一次,发现他们把助手拉进来了。再说一次,我完全同意命名空间静态类的方法比请求的方法更适合 - 或推荐的 -大多数时候。事实是,helpers 并不是真正的 Laravel 方式,而是 CodeIgniter 2.x 的遗留物,仍未被淘汰。因此,我对这种方法没有完全按照要求回答 OP 的迂腐做法更多的是试图强调这样一个事实,即你没有得到帮助,而是得到更好的东西。
    • 对于 Laravel 8(我在这个版本上测试过),在 composer dump-autoload 之前,你需要运行:php artisan config:cache 来清除文件 config/app.php 的缓存。然后它会工作
    【解决方案3】:

    我最初的想法也是作曲家自动加载,但对我来说它并不像 Laravel 5ish。 L5 大量使用服务提供者,它们是引导您的应用程序的东西。

    首先,我在app 目录中创建了一个名为Helpers 的文件夹。然后在Helpers 文件夹中,我为我想要添加的功能添加了文件。拥有一个包含多个文件的文件夹可以让我们避免一个大文件变得太长且难以管理。

    接下来我通过运行 artisan 命令创建了一个HelperServiceProvider.php

    artisan make:provider HelperServiceProvider
    

    register 方法中我添加了这个sn-p

    public function register()
    {
        foreach (glob(app_path().'/Helpers/*.php') as $filename){
            require_once($filename);
        }
    }
    

    最后在 providers 数组中的 config/app.php 中注册服务提供者

    'providers' => [
        'App\Providers\HelperServiceProvider',
    ]
    

    现在您的Helpers 目录中的任何文件都已加载,可以使用了。

    2016 年 2 月 22 日更新

    这里有很多不错的选择,但如果我的回答对你有用,我会继续制作一个包,以这种方式包含助手。您可以使用该软件包来获得灵感,也可以随时使用 Composer 下载它。它有一些我经常使用的内置助手(但默认情况下它们都是不活动的),并允许您使用简单的 Artisan 生成器制作自己的自定义助手。它还解决了响应者使用映射器的建议,并允许您明确定义要加载的自定义帮助程序,或者默认情况下自动加载帮助程序目录中的所有 PHP 文件。非常感谢您的反馈和 PR!

    composer require browner12/helpers
    

    Github:browner12/helpers

    【讨论】:

    • 对于只需要添加几个函数的人来说,composer autoload 非常好,但对于我们这些可能有很多辅助函数的人来说,多文件组织是必须的。这个解决方案本质上是我在 L4 中所做的,除了我在我的 start.php 文件中注册了文件(这不是很好,但在当时起到了它的作用)。您对加载多个文件有其他建议吗?
    • 如果您有多个文件,请将它们全部添加到您的 composer.json 文件中。在此处添加 5 到 10 行代码会让 方式 比您在此处的内容更有意义。
    • 我认为这种技术有很多优点。它优雅而高效,因为您不必记住每次创建帮助文件时都要弄乱 composer.json 文件。
    • 非常好的解决方案。我唯一不同意的是你添加文件的方式,我认为应该是一个映射器,我们在其中添加我们要加载的文件的名称。想想错误!如果其中一个文件中只有一个帮助程序失败,那么您应该删除所有这些帮助程序,或者让站点损坏直到您解决它。
    • 你使用 App\Providers 命名空间吗?我如何从控制器和视图中调用该助手。抱歉,菜鸟问题。
    【解决方案4】:

    这是JeffreyWay在这个Laracasts Discussion中所建议的。

    1. 在您的app/Http 目录中,创建一个helpers.php 文件并添加您的函数。
    2. composer.jsonautoload 块中,添加"files": ["app/Http/helpers.php"]
    3. 运行composer dump-autoload

    【讨论】:

    • 帮助程序可能不是仅 HTTP。 app/helpers.phpapp/Helpers/ 似乎是一个更好的地方。
    • 如果我们在共享服务器上并且没有使用composer dump-autoload 的选项怎么办?
    • @user3201500 这是另一个问题,如果您想遵循上述答案,您可能需要手动执行。或者您可以从其他答案中进行选择。要手动反映composer dump-autoload,您可以按照以下方式操作:developed.be/2014/08/29/composer-dump-autoload-laravel
    【解决方案5】:

    在 SO 和 Google 上筛选了各种答案后,我仍然找不到最佳方法。大多数答案建议我们离开应用程序并依靠 3rd 方工具 Composer 来完成这项工作,但我不相信仅仅为了包含文件而耦合到工具是明智的。

    Andrew Brown's answer 最接近我认为应该接近的方式,但是(至少在 5.1 中),服务提供者步骤是不必要的。 Heisian's answer 突出了PSR-4 的使用,这让我们更近了一步。这是我在视图中对助手的最终实现:

    首先,在您的应用程序目录中的任意位置创建一个帮助文件,并带有命名空间:

    namespace App\Helpers;
    
    class BobFinder
    {
        static function bob()
        {
            return '<strong>Bob?! Is that you?!</strong>';
        }
    }
    

    接下来,在config\app.php 中为您的班级设置别名,在aliases 数组中:

    'aliases' => [
        // Other aliases
        'BobFinder' => App\Helpers\BobFinder::class
    ]
    

    这就是您需要做的所有事情。 PSR-4 和别名应该将帮助程序公开给您的视图,因此在您的视图中,如果您键入:

    {!! BobFinder::bob() !!}
    

    它应该输出:

    <strong>Bob?! Is that you?!</strong>
    

    【讨论】:

    • 感谢您发布此信息。正如@Dan-Hunsaker 在我的解决方案中指出的那样,我们仍然没有最终得到一个全局命名空间函数,即能够简单地编写{!! bob() !!}。将进行更多搜索,看看是否可能
    • 我想了很多,试图让bob() 真正全球化并不是明智之举。命名空间的存在是有原因的,我们不应该在基本 PHP 函数旁边调用 bob()。我会将您的别名位添加到我的代码中 - 谢谢!
    • 我觉得这是最好的
    • @AndrewBrown 不幸的是,几乎 Laravel 文档中的每个示例都使用外观,没有任何警告或建议何时以及何时不使用它们。 Laravel 的新手很难知道他们可以选择不使用它们,以及这样做的影响是什么。
    • @AndrewBrown 这不是门面。这是 PSR-4 自动加载。 php-fig.org/psr/psr-4
    【解决方案6】:

    Laravel 5 中的自定义刀片指令

    是的,还有另一种方法可以做到这一点!

    第 1 步:注册自定义 Blade 指令:

    <?php // code in app/Providers/AppServiceProvider.php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    use Blade; // <-- This is important! Without it you'll get an exception.
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
         public function boot()
         {
             // Make a custom blade directive:
             Blade::directive('shout', function ($string) {
                 return trim(strtoupper($string), '(\'\')');
             });
    
             // And another one for good measure:
             Blade::directive('customLink', function () {
                 return '<a href="#">Custom Link</a>';
             });
         }
        ...
    

    第 2 步:使用您的自定义 Blade 指令:

    <!-- // code in resources/views/view.blade.php -->
    
    @shout('this is my custom blade directive!!')
    <br />
    @customLink
    

    输出:

    这是我的自定义刀片指令!!
    Custom Link


    来源:https://laravel.com/docs/5.1/blade#extending-blade

    补充阅读:https://mattstauffer.co/blog/custom-conditionals-with-laravels-blade-directives


    如果您想了解如何最好地制作可以在任何地方使用的自定义类,请参阅Custom Classes in Laravel 5, the Easy Way

    【讨论】:

    • 这应该被标记为最佳答案,因为问题是“避免在某些视图之间重复代码”。关键字是视图。 :)
    • @heisian 如何将变量传递给自定义指令?
    【解决方案7】:

    这是我的 HelpersProvider.php 文件:

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class HelperServiceProvider extends ServiceProvider
    {
        protected $helpers = [
            // Add your helpers in here
        ];
    
        /**
         * Bootstrap the application services.
         */
        public function boot()
        {
            //
        }
    
        /**
         * Register the application services.
         */
        public function register()
        {
            foreach ($this->helpers as $helper) {
                $helper_path = app_path().'/Helpers/'.$helper.'.php';
    
                if (\File::isFile($helper_path)) {
                    require_once $helper_path;
                }
            }
        }
    }
    

    您应该在app 文件夹下创建一个名为Helpers 的文件夹,然后在其中创建一个名为whatever.php 的文件并在$helpers 数组中添加字符串whatever

    完成!

    编辑

    我不再使用这个选项,我目前正在使用 composer 来加载静态文件,比如 helpers。

    您可以直接在以下位置添加助手:

    ...
    "autoload": {
        "files": [
            "app/helpers/my_helper.php",
            ...
        ]
    },
    ...
    

    【讨论】:

    • 除了性能之外还有其他原因来创建映射器,而不是像 Andrew Brown 所写的那样用glob() 加载目录中的所有文件吗?如果您希望能够指定要包含的文件,为什么不指定 composer.json 中的文件以按照 Joseph Silber 所写的方式自动加载它们呢?为什么你更喜欢这个解决方案?我并不是说这是一个糟糕的解决方案,我只是好奇。
    • 使用映射方法可以更容易地选择性地启用/禁用帮助程序,例如,如果某个帮助程序文件包含中断错误。也就是说,服务提供者中的映射文件与composer.json 中的映射文件没有太大区别,除了两点 - 首先,它将映射保存在应用程序本身中,而不是元数据文件;其次,它不需要您每次更改要加载的文件列表时都重新运行composer dump-autoload
    • 不需要includerequire,Laravel 已经内置了 PSR-4 自动加载:php-fig.org/psr/psr-4
    • 使用 PSR-4 和 composer 将不允许您打开/关闭助手。
    • @PabloEzequielLeone 我将如何在控制器或刀片文件中使用它?如果您担心不是每次都为所有控制器加载所有助手,这看起来是最好的选择,但对于 Laravel 的初学者(比如我自己)来说并不好。
    【解决方案8】:

    对于我的 Laravel 项目中的自定义帮助程序库,我在 Laravel/App 目录中创建了一个名为 Libraries 的文件夹,并且在库目录中,我为不同的帮助程序库创建了各种文件。

    创建我的帮助文件后,我只需将所有这些文件包含在我的 composer.json 文件中,如下所示

    ...
    "autoload": {
            "classmap": [
                "database"
            ],
            "files": [
                "app/Libraries/commonFunctions.php"
            ],
            "psr-4": {
                "App\\": "app/"
            }
        },
    ...
    

    并执行

    composer dump-autoload
    

    【讨论】:

    • composer dump-autoloadcomposer dumpautoload 也有效,事实上 composer du 也有效...
    • 您提到您在 app/Libraries 文件夹中添加了不同的帮助程序库,但在 composer.json 文件中只添加了一个文件。您是否在 commonFunction.php 文件中包含了帮助文件?
    • 这就像一个魅力!我为此浪费了将近一天的时间,然后我找到了这个答案。非常感谢!
    【解决方案9】:

    由于 OP 要求最佳实践,我认为我们仍然缺少一些好的建议。

    单个 helpers.php 文件远非一个好习惯。首先,因为您混合了许多不同类型的功能,因此您违反了良好的编码原则。此外,这可能不仅会损害代码文档,还会损害代码指标,例如循环复杂度可维护性指数Halstead Volume时间>。功能越多越差。

    代码文档可以使用phpDocumentor 之类的工具,但使用Samiwon't render procedural files。 Laravel API 文档就是这样——没有辅助函数文档:https://laravel.com/api/5.4

    可以使用PhpMetrics 等工具分析代码指标。使用 PhpMetrics 版本 1.x 分析 Laravel 5.4 框架代码会为 src/Illuminate/Foundation/helpers.phpsrc/Illuminate/Support/helpers.php 文件提供非常糟糕的 CC/MI/HV 指标。

    多个上下文帮助文件(例如,string_helpers.phparray_helpers.php 等)肯定会改善这些不良指标,从而使代码更易于维护。根据使用的代码文档生成器,这已经足够了。

    可以通过使用带有静态方法的辅助类来进一步改进它,这样它们就可以使用命名空间进行上下文化。就像 Laravel 已经对 Illuminate\Support\StrIlluminate\Support\Arr 类所做的那样。这改进了代码度量/组织和文档。可以使用类别名使它们更易于使用。

    使用类进行结构化可以更好地组织代码和文档,但另一方面,我们最终会失去那些简短易记的全局函数。我们可以通过为这些静态类方法创建函数别名来进一步改进该方法。这可以手动或动态完成。

    Laravel 在内部使用第一种方法,即在映射到静态类方法的过程帮助文件中声明函数。这可能不是理想的选择,因为您需要重新声明所有内容(文档块/参数)。
    我个人使用动态方法和 HelperServiceProvider 类在执行时创建这些函数:

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class HelperServiceProvider extends ServiceProvider
    {
        /**
         * The helper mappings for the application.
         *
         * @var array
         */
        protected $helpers = [
            'uppercase' => '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()
        {
            //
        }
    }
    

    可以说这是过度工程,但我不这么认为。它运行良好,与预期相反,至少在使用 PHP 7.x 时不会花费相关的执行时间。

    【讨论】:

      【解决方案10】:

      您实际上可以在别名下添加到您的 config/app.php 文件中,而不是包含您的自定义帮助程序类。

      应该是这样的。

       'aliases' => [ 
          ...
          ...
          'Helper' => App\Http\Services\Helper::class,
       ]
      

      然后到你的控制器,使用方法'use Helper'包含Helper,这样你就可以简单地调用你的Helper类的一些方法。

      eg. Helper::some_function();
      

      或者在资源视图中,您可以直接调用 Helper 类。

      eg. {{Helper::foo()}}
      

      但这仍然是要遵循的开发人员编码风格方法。我们可能有不同的解决问题的方法,我只是想分享一下我对初学者也有的。

      【讨论】:

        【解决方案11】:

        这是我创建的一个 bash shell 脚本,用于非常快速地制作 Laravel 5 外观。

        在你的 Laravel 5 安装目录中运行它。

        这样称呼它:

        make_facade.sh -f <facade_name> -n '<namespace_prefix>'
        

        例子:

        make_facade.sh -f helper -n 'App\MyApp'
        

        如果您运行该示例,它将在“your_laravel_installation_dir/app/MyApp”下创建目录FacadesProviders

        它将创建以下 3 个文件并将它们输出到屏幕:

        ./app/MyApp/Facades/Helper.php
        ./app/MyApp/Facades/HelperFacade.php
        ./app/MyApp/Providers/HelperServiceProvider.php
        

        完成后会显示类似如下的信息:

        ===========================
            Finished
        ===========================
        
        Add these lines to config/app.php:
        ----------------------------------
        Providers: App\MyApp\Providers\HelperServiceProvider,
        Alias: 'Helper' => 'App\MyApp\Facades\HelperFacade',
        

        所以更新 'config/app.php' 中的 Providers 和 Alias 列表

        运行composer -o dumpautoload

        “./app/MyApp/Facades/Helper.php”最初看起来像这样:

        <?php
        
        namespace App\MyApp\Facades;
        
        
        class Helper
        {
            //
        }
        

        现在只需在“./app/MyApp/Facades/Helper.php”中添加您的方法。

        这是我添加 Helper 函数后“./app/MyApp/Facades/Helper.php”的样子。

        <?php
        
        namespace App\MyApp\Facades;
        
        use Request;
        
        class Helper
        {
            public function isActive($pattern = null, $include_class = false)
            {
                return ((Request::is($pattern)) ? (($include_class) ? 'class="active"' : 'active' ) : '');
            }
        }
        
        This is how it would be called:
        ===============================
        
        {!!  Helper::isActive('help', true) !!}
        

        这个函数需要一个模式并且可以接受一个可选的第二个布尔参数。

        如果当前 URL 与传递给它的模式匹配,它将输出 'active'(如果您将 'true' 作为函数调用的第二个参数添加,则输出 'class="active"')。

        我用它来突出显示处于活动状态的菜单。

        以下是我的脚本的源代码。我希望你觉得它有用,如果你有任何问题,请告诉我。

        #!/bin/bash
        
        display_syntax(){
            echo ""
            echo "  The Syntax is like this:"
            echo "  ========================"
            echo "      "$(basename $0)" -f <facade_name> -n '<namespace_prefix>'"
            echo ""
            echo "  Example:"
            echo "  ========"
            echo "      "$(basename $0) -f test -n "'App\MyAppDirectory'"
            echo ""
        }
        
        
        if [ $# -ne 4 ]
        then
            echo ""
            display_syntax
            exit
        else
        # Use > 0 to consume one or more arguments per pass in the loop (e.g.
        # some arguments don't have a corresponding value to go with it such
        # as in the --default example).
            while [[ $# > 0 ]]
            do
                key="$1"
                    case $key in
                    -n|--namespace_prefix)
                    namespace_prefix_in="$2"
                    echo ""
                    shift # past argument
                    ;;
                    -f|--facade)
                    facade_name_in="$2"
                    shift # past argument
                    ;;
                    *)
                            # unknown option
                    ;;
                esac
                shift # past argument or value
            done
        fi
        echo Facade Name = ${facade_name_in}
        echo Namespace Prefix = $(echo ${namespace_prefix_in} | sed -e 's#\\#\\\\#')
        echo ""
        }
        
        
        function display_start_banner(){
        
            echo '**********************************************************'
            echo '*          STARTING LARAVEL MAKE FACADE SCRIPT'
            echo '**********************************************************'
        }
        
        #  Init the Vars that I can in the beginning
        function init_and_export_vars(){
            echo
            echo "INIT and EXPORT VARS"
            echo "===================="
            #   Substitution Tokens:
            #
            #   Tokens:
            #   {namespace_prefix}
            #   {namespace_prefix_lowerfirstchar}
            #   {facade_name_upcase}
            #   {facade_name_lowercase}
            #
        
        
            namespace_prefix=$(echo ${namespace_prefix_in} | sed -e 's#\\#\\\\#')
            namespace_prefix_lowerfirstchar=$(echo ${namespace_prefix_in} | sed -e 's#\\#/#g' -e 's/^\(.\)/\l\1/g')
            facade_name_upcase=$(echo ${facade_name_in} | sed -e 's/\b\(.\)/\u\1/')
            facade_name_lowercase=$(echo ${facade_name_in} | awk '{print tolower($0)}')
        
        
        #   Filename: {facade_name_upcase}.php  -  SOURCE TEMPLATE
        source_template='<?php
        
        namespace {namespace_prefix}\Facades;
        
        class {facade_name_upcase}
        {
            //
        }
        '
        
        
        #  Filename: {facade_name_upcase}ServiceProvider.php    -   SERVICE PROVIDER TEMPLATE
        serviceProvider_template='<?php
        
        namespace {namespace_prefix}\Providers;
        
        use Illuminate\Support\ServiceProvider;
        use App;
        
        
        class {facade_name_upcase}ServiceProvider extends ServiceProvider {
        
            public function boot()
            {
                //
            }
        
            public function register()
            {
                App::bind("{facade_name_lowercase}", function()
                {
                    return new \{namespace_prefix}\Facades\{facade_name_upcase};
                });
            }
        
        }
        '
        
        #  {facade_name_upcase}Facade.php   -   FACADE TEMPLATE
        facade_template='<?php
        
        namespace {namespace_prefix}\Facades;
        
        use Illuminate\Support\Facades\Facade;
        
        class {facade_name_upcase}Facade extends Facade {
        
            protected static function getFacadeAccessor() { return "{facade_name_lowercase}"; }
        }
        '
        }
        
        
        function checkDirectoryExists(){
            if [ ! -d ${namespace_prefix_lowerfirstchar} ]
            then
                echo ""
                echo "Can't find the namespace: "${namespace_prefix_in}
                echo ""
                echo "*** NOTE:"
                echo "           Make sure the namspace directory exists and"
                echo "           you use quotes around the namespace_prefix."
                echo ""
                display_syntax
                exit
            fi
        }
        
        function makeDirectories(){
            echo "Make Directories"
            echo "================"
            mkdir -p ${namespace_prefix_lowerfirstchar}/Facades
            mkdir -p ${namespace_prefix_lowerfirstchar}/Providers
            mkdir -p ${namespace_prefix_lowerfirstchar}/Facades
        }
        
        function createSourceTemplate(){
            source_template=$(echo "${source_template}" | sed -e 's/{namespace_prefix}/'${namespace_prefix}'/g' -e 's/{facade_name_upcase}/'${facade_name_upcase}'/g' -e 's/{facade_name_lowercase}/'${facade_name_lowercase}'/g')
            echo "Create Source Template:"
            echo "======================="
            echo "${source_template}"
            echo ""
            echo "${source_template}" > ./${namespace_prefix_lowerfirstchar}/Facades/${facade_name_upcase}.php
        }
        
        function createServiceProviderTemplate(){
            serviceProvider_template=$(echo "${serviceProvider_template}" | sed -e 's/{namespace_prefix}/'${namespace_prefix}'/g' -e 's/{facade_name_upcase}/'${facade_name_upcase}'/g' -e 's/{facade_name_lowercase}/'${facade_name_lowercase}'/g')
            echo "Create ServiceProvider Template:"
            echo "================================"
            echo "${serviceProvider_template}"
            echo ""
            echo "${serviceProvider_template}" > ./${namespace_prefix_lowerfirstchar}/Providers/${facade_name_upcase}ServiceProvider.php
        }
        
        function createFacadeTemplate(){
            facade_template=$(echo "${facade_template}" | sed -e 's/{namespace_prefix}/'${namespace_prefix}'/g' -e 's/{facade_name_upcase}/'${facade_name_upcase}'/g' -e 's/{facade_name_lowercase}/'${facade_name_lowercase}'/g')
            echo "Create Facade Template:"
            echo "======================="
            echo "${facade_template}"
            echo ""
            echo "${facade_template}" > ./${namespace_prefix_lowerfirstchar}/Facades/${facade_name_upcase}Facade.php
        }
        
        
        function serviceProviderPrompt(){
            echo "Providers: ${namespace_prefix_in}\Providers\\${facade_name_upcase}ServiceProvider,"
        }
        
        function aliasPrompt(){
            echo "Alias: '"${facade_name_upcase}"' => '"${namespace_prefix_in}"\Facades\\${facade_name_upcase}Facade'," 
        }
        
        #
        #   END FUNCTION DECLARATIONS
        #
        
        
        ###########################
        ## START RUNNING SCRIPT  ##
        ###########################
        
        display_start_banner
        
        init_and_export_vars
        makeDirectories 
        checkDirectoryExists
        echo ""
        
        createSourceTemplate
        createServiceProviderTemplate
        createFacadeTemplate
        echo ""
        echo "==========================="
        echo "  Finished TEST"
        echo "==========================="
        echo ""
        echo "Add these lines to config/app.php:"
        echo "----------------------------------"
        serviceProviderPrompt
        aliasPrompt
        echo ""
        

        【讨论】:

          【解决方案12】:

          创建自定义助手目录: 首先在 app 目录中创建 Helpers 目录。 创建 hlper 类定义: 现在让我们创建一个简单的辅助函数来连接两个字符串。在 /app/Helpers/MyFuncs.php 中新建文件 MyFuncs.php 添加如下代码

          <?php
          
          namespace App\Helpers;
          
          class MyFuncs {
          
              public static function full_name($first_name,$last_name) {
                  return $first_name . ', '. $last_name;   
              }
          }
          

          命名空间 App\Helpers;在 App 命名空间下定义 Helpers 命名空间。 class MyFuncs {…} 定义了辅助类 MyFuncs。 public static function full_name($first_name,$last_name) {…} 定义了一个静态函数,接受两个字符串参数并返回一个串联的字符串

          助手服务提供类

          服务提供者用于自动加载类。我们需要定义一个服务提供者,它将在 /app/Helpers 目录中加载我们所有的帮助类。

          运行以下工匠命令:

          php artisan make:provider HelperServiceProvider

          文件将在/app/Providers/HelperServiceProvider.php中创建

          Open /app/Providers/HelperServiceProvider.php
          

          添加以下代码:

          <?php 
          
          namespace App\Providers;
          
          use Illuminate\Support\ServiceProvider;
          
          class HelperServiceProvider extends ServiceProvider {
          
             /**
              * Bootstrap the application services.
              *
              * @return void
              */
             public function boot()
             {
                //
             }
          
             /**
              * Register the application services.
              *
              * @return void
              */
             public function register()
             {
                  foreach (glob(app_path().'/Helpers/*.php') as $filename){
                      require_once($filename);
                  }
             }
          }
          

          这里,

          namespace App\Providers; defines the namespace provider
          use Illuminate\Support\ServiceProvider; imports the ServiceProvider class namespace
          class HelperServiceProvider extends ServiceProvider {…} defines a class HelperServiceProvider that extends the ServiceProvider class
          public function boot(){…} bootstraps the application service
          public function register(){…} is the function that loads the helpers
          foreach (glob(app_path().'/Helpers/*.php') as $filename){…} loops through all the files in /app/Helpers directory and loads them.
          

          我们现在需要注册 HelperServiceProvider 并为我们的助手创建一个别名。

          打开/config/app.php文件

          找到提供者数组变量

          添加下面一行

          App\Providers\HelperServiceProvider::class,
          

          找到别名数组变量

          添加以下行

          'MyFuncs' => App\Helpers\MyFuncs::class,
          

          保存更改 使用我们的自定义助手

          我们将创建一个路由来调用我们的自定义辅助函数 Open /app/routes.php

          添加以下路由定义

          Route::get('/func', function () {
              return MyFuncs::full_name("John","Doe");
          });
          

          这里,

          return MyFuncs::full_name("John","Doe"); calls the static function full_name in MyFuncs class
          

          【讨论】:

            【解决方案13】:

            首先在 App\Http 目录中创建 helpers.php。 然后在composer.json里面添加如下代码

            "autoload": {
                    "classmap": [
                        "database"
                    ],
                    "files": [
                        "app/Http/helpers.php"
                    ],
                    "psr-4": {
                        "App\\": "app/"
                    }
                },
            

            接下来运行以下命令

            composer dump-autoload
            

            现在您可以在 helpers.php 文件中定义您的自定义函数。

            【讨论】:

              【解决方案14】:

              在 app/Helper/Helpers.php 中创建 Helpers.php

              namespace App\Helper
              class Helpers
              {
              
              
              }
              

              添加作曲家和作曲家更新

               "autoload": {
                      "classmap": [
                          "database/seeds",
                          "database/factories",
                          "database","app/Helper/Helpers.php"
                      ],
                      "psr-4": {
                          "App\\": "app/"
                      },
                       "files": ["app/Helper/Helpers.php"]
                  },
              

              在控制器中使用

              使用 App\Helper\Helpers

              在视图中使用 更改 config->app.php 文件

                 'aliases' => [
                  ...
                  'Helpers'   => 'App\Helper\Helpers'
                  ],
              

              通话可见

              <?php echo Helpers::function_name();  ?>
              

              【讨论】:

              • 谢谢,您介意扩展一下您的解释吗?
              • 如果类是命名空间的,在composer.json 中添加文件是没有用的,因为 psr-4 自动加载会完成这项工作。
              • @abhishekkumar - 对 Lumen 8.0 的任何建议。提前致谢。
              • 我为 Lumen 8 尝试了相同的解决方案,但出现错误“致命错误:无法声明类 MasterFunctionsHelper,因为该名称已在 /Applications/MAMP/htdocs/laravelprojects/project_api/app/ 中使用第 3 行的 Helpers/MasterFunctionsHelper.php"
              • @Kamlesh 命名空间问题,这个链接会帮你stackoverflow.com/questions/40406418/…
              【解决方案15】:

              **

              • 状态助手

              ** 创建新的助手

              <?php
              
              namespace App\Helpers;
              
              use Illuminate\Database\Eloquent\Collection;
              
              class StatusHelper
              {
               protected static $_status = [
                      1=> [
                          'value' => 1,
                          'displayName' => 'Active',
                      ],
                      2 => [
                          'value' => 2,
                          'displayName' => 'Inactive',
                      ],
                      3 => [
                          'value' => 3,
                          'displayName' => 'Delete',
                      ],
              
                  ];
              
                   public static function getStatusesList()
                  {
                      $status = (new Collection(self::$_status))->pluck('displayName', 'value')->toArray();
              
              
                      return $status;
                  }
              }
              

              用于控制器和任何视图文件

              use App\Helpers\StatusHelper;
              
              class ExampleController extends Controller
              {
                      public function index()
                      {
                          $statusList = StatusHelper::getStatusesList();
              
                          return view('example.index', compact('statusList'));
                      }
              }
              

              【讨论】:

                【解决方案16】:

                编写自定义助手的最佳实践是

                1) 在项目根目录的app 目录下,创建一个名为 Helpers 的文件夹(仅用于分隔和结构化代码)。

                2) 在文件夹内写入psr-4文件或普通php文件

                如果 PHP 文件是 psr-4 格式,那么它将被自动加载,否则在项目根目录下的 composer.json 中添加以下行

                autoload键内,新建一个名为files的键,用于在自动加载时加载文件,在files对象内添加从app目录开始的路径,这里是一个例子。

                "autoload": {
                    "classmap": [
                        "database"
                    ],
                    "psr-4": {
                        "App\\": "app/"
                    },
                    "files": [
                        "app/Helpers/customHelpers.php"
                    ]
                },
                "autoload-dev": {
                    "classmap": [
                        "tests/TestCase.php"
                    ]
                },
                

                PS : 如果文件未加载,请尝试运行 composer dump-autoload

                【讨论】:

                  【解决方案17】:

                  我使用的另一种方式是: 1)在 app\FolderName\fileName.php 中创建了一个文件,并在其中包含此代码,即

                  <?php
                  namespace App\library
                  {
                   class hrapplication{
                    public static function libData(){
                     return "Data";
                    }
                   }
                  }
                  ?>
                  

                  2) 之后在我们的刀片中

                   $FmyFunctions = new \App\FolderName\classsName;
                    echo $is_ok = ($FmyFunctions->libData());
                  

                  就是这样。它有效

                  【讨论】:

                    【解决方案18】:

                    在目录 bootstrap\autoload.php

                    require __DIR__.'/../vendor/autoload.php';
                    require __DIR__.'/../app/Helpers/function.php'; //add
                    

                    添加这个文件

                    app\Helpers\function.php
                    

                    【讨论】:

                      【解决方案19】:

                      这里有一些很好的答案,但我认为这是最简单的。 在 Laravel 5.4(以及更早的版本)中,您可以在方便的地方创建一个类,例如 App/Libraries/Helper.php

                      class Helper() {
                          public function uppercasePara($str) {
                              return '<p>' .strtoupper($str). '<p>;
                          }
                      }
                      

                      然后您可以像这样在 Blade 模板中简单地调用它:

                      @inject('helper', \App\Libraries\Helper)
                      {{ $helper->drawTimeSelector() }}
                      

                      如果您不想使用@inject,那么只需将“uppercasePara”函数设为静态并将调用嵌入到 Blade 模板中,如下所示:

                      {{ \App\Libraries\Helper::drawTimeSelector() }}
                      

                      不需要别名。 Laravel 自动解析具体类。

                      【讨论】:

                        【解决方案20】:

                        在 Laravel 5.3 及更高版本中,Laravel 团队将所有程序文件 (routes.php) 移出 app/ 目录,并且整个 app/ 文件夹是 psr-4 自动加载的。接受的答案在这种情况下会起作用,但我觉得不对。

                        所以我所做的就是在我的项目的根目录下创建了一个helpers/ 目录并将帮助文件放在其中,然后在我的composer.json 文件中我这样做了:

                        ...
                        "autoload": {
                            "classmap": [
                                "database"
                            ],
                            "psr-4": {
                                "App\\": "app/"
                            },
                            "files": [
                                "helpers/ui_helpers.php"
                            ]
                        },
                        ...
                        

                        这样我的app/ 目录仍然是一个 psr-4 自动加载的目录,并且帮助程序组织得更好。

                        【讨论】:

                          【解决方案21】:

                          App/Helpers/ 中创建新文件examplehelper.php 然后添加composer.json文件

                          "autoload": { "classmap": [ "database"], "psr-4": { "App\\": "app/" },
                          "files": ["helpers/examplehelper.php" ]},
                          

                          【讨论】:

                          • 这与接受的答案中的解决方案非常相似。在回答已有答案的旧问题时,请确保提供新颖的解决方案或比现有答案更好的解释。
                          猜你喜欢
                          • 2015-12-01
                          • 2018-02-25
                          • 2016-04-25
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-01-10
                          • 2018-09-04
                          • 2018-12-13
                          • 2022-08-04
                          相关资源
                          最近更新 更多