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

view.blade.php

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

它们基本上是文本格式化函数。我应该如何定义全局可用的帮助函数,如fooFormatText()?


当前回答

创建自定义助手目录: 首先在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 namespace下定义了Helpers命名空间。 类MyFuncs{…}定义了帮助类MyFuncs。 公共静态函数full_name($first_name,$last_name){…}定义了一个静态函数,它接受两个字符串形参并返回一个连接的字符串

帮工服务提供类

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

执行以下artisan命令:

php工匠使:提供者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文件

找到providers数组变量

添加以下行

App\Providers\HelperServiceProvider::class,

定位aliases数组变量

添加以下行

'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

其他回答

创建自定义助手目录: 首先在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 namespace下定义了Helpers命名空间。 类MyFuncs{…}定义了帮助类MyFuncs。 公共静态函数full_name($first_name,$last_name){…}定义了一个静态函数,它接受两个字符串形参并返回一个连接的字符串

帮工服务提供类

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

执行以下artisan命令:

php工匠使:提供者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文件

找到providers数组变量

添加以下行

App\Providers\HelperServiceProvider::class,

定位aliases数组变量

添加以下行

'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

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

单一的helpers.php文件远非一个好的实践。首先,因为你混合了很多不同类型的函数,所以你违背了良好的编码原则。此外,这不仅会损害代码文档,还会损害诸如圈复杂度、可维护性指数和Halstead Volume等代码指标。函数越多,情况就越糟。

使用phpDocumentor这样的工具,代码文档是可以的,但使用Sami,它不会呈现过程性文件。Laravel API文档就是这样一种情况——没有辅助函数文档:https://laravel.com/api/5.4

代码度量可以使用PhpMetrics等工具进行分析。使用PhpMetrics版本1。src/Illuminate/Foundation/helpers.php和src/Illuminate/Support/helpers.php文件的CC/MI/HV指标都非常糟糕。

多个上下文帮助文件(例如。String_helpers.php, array_helpers.php等)肯定会改善这些糟糕的指标,从而使代码更容易维护。根据所使用的代码文档生成器,这就足够了。

可以通过使用带有静态方法的helper类来进一步改进,这样它们就可以使用名称空间进行上下文化。就像Laravel已经对Illuminate\Support\Str和Illuminate\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时不会花费相关的执行时间。

这里有一些很好的答案,但我认为这是最简单的。 在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自动解析具体类。

首先在App\Helpers\Helper.php中创建你的Helper文件/类 就像:

<?php

namespace App\Helpers;

class Helper {

    // Your customer public function
}

然后在Composer.json中定义它 在交通量 然后运行composer dump-autoload

下面是我创建的一个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”下创建目录Facades和Providers。

它将创建以下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”中添加方法。

下面是“。/app/MyApp/Facades/Helper.php”在我添加了一个Helper函数后的样子。

<?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'(或者'class="active"',如果你添加'true'作为函数调用的第二个参数)。

我用它来突出显示激活的菜单。

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

#!/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 ""