Лучшие практики для пользовательских помощников в Laravel 5 [закрыто]

472

Я хотел бы создать вспомогательные функции, чтобы избежать повторения кода между представлениями в Laravel 5:

view.blade.php

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

Это в основном функции форматирования текста. Где и как я могу создать файл с этими функциями?

Калеб Оливейра
источник

Ответы:

595

Создайте 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 в каталоге начальной загрузки . Не забудьте установить его в свой composer.jsonфайл:

"files": [
    "bootstrap/helpers.php"
]
Джозеф Силбер
источник
86
Совет для новичков: используйте эту команду после изменения composer.json. композитор дамп-автозагрузка
Allfarid Моралес Гарсия
11
@ AllfaridMoralesGarcía Или, может быть, просто «полезный совет, так как ответ не дает понять, что вам нужно делать это потом».
Мэтт Макдональд
8
Я одобряю вспомогательные функции, чтобы упростить написание представлений, но я ненавижу, как часто этот ответ упоминается в других ответах. Не поймите меня неправильно, это хороший ответ и правильный ответ, я просто боюсь, что люди будут злоупотреблять этим и снова начнут писать тонны плохо написанного, плохо организованного функционального PHP.
Andrewtweber
40
Я не понимаю этот подход. Предполагается, что Composer - это инструмент для включения библиотек: без него Laravel будет прекрасно работать, а Composer без Laravel. Это предложение говорит нам, чтобы создать файл в нашем приложении, покинуть наше приложение, перейти в Composer, сказать композитору вернуться в наше приложение и включить файл. Laravel четко обрабатывает включение файлов, верно? Зачем нам отказываться от собственной реализации Laravel и использовать этот внешний инструмент для включения файла для нас, тем самым связывая наше приложение с Composer? Это лень или я что-то упустил?
августа
6
Laravel использует автозагрузчик composer, чтобы знать, куда включать все библиотеки и файлы, на которые он опирается. На это ссылаются в bootstrap / autoload.php. Прочитайте комментарий в этом файле. Подход состоит в том, чтобы добавить ссылку на файл в composer.json, а затем «dump autoload», который регенерирует автозагрузчик composer, чтобы Laravel мог его найти. Использование коллекции «файлы» Composer - это хороший способ добавить библиотеки или одноразовые файлы функций, которые не аккуратно упакованы в пакеты Composer. Хорошо иметь место для всех ситуаций "кстати, я должен включить этот один странный файл".
Филипп Харрингтон
370

Пользовательские классы в Laravel 5, легкий путь

Этот ответ применим к общим пользовательским классам в Laravel. Для более подробного ответа о Blade см. Пользовательские директивы Blade в Laravel 5 .

Шаг 1. Создайте свой файл помощников (или другого пользовательского класса) и задайте ему соответствующее пространство имен. Напишите свой класс и метод:

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

heisian
источник
35
Чтобы быть ясным, этот ответ на самом деле не касается помощников, которые являются глобальными функциями пространства имен. Вместо этого он поощряет преобразование помощников в методы класса. Как правило, это лучший подход, но на самом деле он не отвечает на заданный здесь вопрос, поэтому другие ответы настолько сложны для сравнения.
Дан Хансакер
1
Функция-помощник означает, что она доступна и в Blade. Как сделать эту функцию доступной в Blade? Вы не можете вызвать Helper :: prettyJason (параметры) в блейде.
MaXi32
@ MaXi32, вы можете добавить класс в aliasesмассив app/config.php: 'Helper' => App\Helpers\Helper::class, Тогда вы сможете Helper::prettyJson();нормально вызывать blade.
Heisian
@DanHunsaker отредактировал, чтобы прямо ответить на вопрос, и это все тот же простой подход. Вы также можете просто написать свои собственные директивы
блейдов
1
Да, я однажды покопался в фреймворке и нашел, куда они втягивали помощников. И снова, я полностью согласен, что методы статических классов с пространством имен гораздо лучше подходят, чем то, что запрашивается - или рекомендуется - большую часть времени. Дело в том, что на самом деле помощники - это не The Laravel Way, а скорее пережиток CodeIgniter 2.x, который до сих пор не отменен. Таким образом, моя педантичность в отношении такого подхода, не отвечающего ОП точно так, как было задано, - это скорее попытка подчеркнуть тот факт, что у вас нет помощников, а скорее что-то лучшее.
Дэн Хансакер
315

Моей первоначальной мыслью была также автозагрузка композитора, но она мне показалась не очень хорошей. L5 интенсивно использует поставщиков услуг, именно они запускают ваше приложение.

Для начала я создал папку в своем appкаталоге с именем Helpers. Затем в Helpersпапке я добавил файлы для функций, которые я хотел добавить. Наличие папки с несколькими файлами позволяет нам избежать одного большого файла, который становится слишком длинным и неуправляемым.

Затем я создал HelperServiceProvider.phpкоманду ремесленника:

artisan make:provider HelperServiceProvider

В registerметоде я добавил этот фрагмент

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

наконец, зарегистрируйте поставщика услуг в вашем config/app.phpсписке поставщиков

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

Теперь любой файл в вашем Helpersкаталоге загружен и готов к использованию.

ОБНОВЛЕНИЕ 2016-02-22

Здесь есть много хороших вариантов, но если мой ответ сработает для вас, я пошел дальше и составил пакет для включения помощников таким образом. Вы можете использовать пакет для вдохновения или загрузить его с помощью Composer. Он имеет несколько встроенных помощников, которые я часто использую (но которые по умолчанию неактивны) и позволяет вам создавать свои собственные помощники с помощью простого генератора Artisan. Он также учитывает предложение респондента об использовании картографа и позволяет явно определять настраиваемые помощники для загрузки или по умолчанию автоматически загружать все файлы PHP в каталоге помощников. Отзывы и PR очень ценятся!

composer require browner12/helpers

Github: browner12 / helpers

Эндрю Браун
источник
29
для людей, у которых есть только несколько функций, которые им нужно добавить, автозагрузка композитора отлично подходит, но для тех из нас, у кого может быть много вспомогательных функций, необходима организация нескольких файлов. это решение, по сути, то, что я делал в L4, за исключением того, что я зарегистрировал файлы в своем start.phpфайле (что было не очень хорошо, но в то время служило своей цели). у вас есть другое предложение для загрузки нескольких файлов?
Эндрю Браун
7
Если у вас есть несколько файлов, добавьте их все в свой файл composer.json. Добавление даже 5-10 строк имеет куда больше смысла, чем то, что есть у вас здесь.
Джозеф Силбер
22
Я думаю, что эта техника имеет много достоинств. Это элегантно и эффективно, потому что вам не нужно каждый раз связываться с файлом composer.json при создании вспомогательного файла.
Импето
8
Действительно хорошее решение. Единственное, с чем я не согласен, это то, как вы добавляете файлы, я думаю, что вместо этого должен быть картограф, в который мы добавляем имя файла, который мы хотим загрузить. Думай об ошибках! если в одном из файлов, который выходит из строя, есть только один помощник, вы должны удалить их все или сломать сайт, пока не решите его.
Пабло Эзекьель Леоне
3
Используете ли вы пространство имен App \ Providers? Как я называю этого помощника из контроллера и просмотра. Извините, нуб вопрос.
Ченгрук
79

Это то, что предлагается JeffreyWayв этом обсуждении Laracasts .

  1. В вашем app/Httpкаталоге создайте helpers.phpфайл и добавьте свои функции.
  2. Внутри composer.json, в autoloadблоке, добавить "files": ["app/Http/helpers.php"].
  3. Беги composer dump-autoload.
itsazzad
источник
15
Помощники могут быть не только HTTP. app/helpers.phpили, app/Helpers/кажется, лучше.
сентября
1
Что делать, если мы находимся на общем сервере и не можем использовать composer dump-autoload ?
user3201500
@ user3201500, это другой вопрос, и вам, возможно, придется сделать это вручную, если вы хотите следовать приведенному выше ответу. Или вы можете выбрать из других ответов. И чтобы отразить это вручную, composer dump-autoloadвы можете выполнить следующие действия: developers.be/2014/08/29/composer-dump-autoload-laravel
itsazzad
55

Просеяв множество ответов о SO и Google, я все еще не мог найти оптимальный подход. Большинство ответов предполагают, что мы оставляем приложение и полагаемся на сторонний инструмент Composer для выполнения этой работы, но я не уверен, что подключение к инструменту просто для включения файла является разумным.

Ответ Эндрю Брауна был ближе всего к тому, как я думаю, к нему следует подходить, но (по крайней мере, в 5.1) шаг поставщика услуг не нужен. Ответ Хейсиана подчеркивает использование 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>
dKen
источник
спасибо за публикацию этого. как указал @ Dan-Hunsaker в моем решении, мы до сих пор не получили функцию с глобальным пространством имен, то есть возможность писать просто {!! bob() !!}. собираюсь сделать еще поиск и посмотреть, возможно ли это
Heisian
1
Я больше думал об этом, и попытка сделать по- bob()настоящему глобальным было бы неразумно. Пространства имен существуют по причине, и мы не должны вызывать bob()наряду с базовыми функциями PHP. Я добавлю ваш бит псевдонима в мой код - спасибо!
Heisian
1
Я считаю, что это лучшее из всех
Джимми Обонио Абор
Почему там extends Helper? Это не кажется мне необходимым.
Берни
@bernie @ user3201500 Извините, у меня был свой базовый класс помощников, от которого унаследованы все мои помощники; extends Helperдействительно не нужно. Спасибо за внимание.
dKen
32

Пользовательские директивы по лезвиям в Ларавел 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

Выходы:

ЭТО МОЙ ТАМОЖЕННЫЙ ДИРЕКТИВ ЛЕЗВИЯ!
Пользовательская ссылка


Источник: https://laravel.com/docs/5.1/blade#extending-blade

Дополнительное чтение: https://mattstauffer.co/blog/custom-conditionals-with-laravels-blade-directives


Если вы хотите узнать, как лучше создавать пользовательские классы, которые можно использовать где угодно , см. Пользовательские классы в Laravel 5, Easy Way

heisian
источник
Это должно быть помечено как лучший ответ, потому что вопрос заключался в том, чтобы «не повторять код между некоторыми представлениями». Ключевое слово ВИДЫ. :)
Александр
23

Это мой файл 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;
            }
        }
    }
}

Вы должны создать папку с именем Helpersв appпапке, затем создать файл с именем whatever.phpвнутри и добавить строку whateverвнутри массива $ helpers.

Выполнено!

редактировать

Я больше не использую эту опцию, в настоящее время я использую Composer для загрузки статических файлов, таких как помощники.

Вы можете добавить помощников непосредственно по адресу:

...
"autoload": {
    "files": [
        "app/helpers/my_helper.php",
        ...
    ]
},
...
Пабло Эзекьель Леоне
источник
Есть ли другие причины, кроме производительности, для создания картографа вместо загрузки всех файлов в каталоге, glob()как писал Эндрю Браун? Если вы хотите иметь возможность указать файлы, которые вы хотите включить, почему бы не указать файлы в composer.jsonдля их автозагрузки, как написал Джозеф Силбер? Почему вы предпочитаете это решение? Я не говорю, что это плохое решение, мне просто любопытно.
Pelmered
3
При отображенном подходе проще выборочно включать / отключать помощников, если, например, один из вспомогательных файлов содержит ошибку прерывания. При этом отображение файлов в поставщике услуг мало чем отличается от этого, composer.jsonза исключением двух моментов: во-первых, карта хранится в самом приложении, а не в файле метаданных; во-вторых, он не требует повторного запуска composer dump-autoloadкаждый раз, когда вы меняете список файлов для загрузки.
Дан Хансакер
Нет необходимости includeили require, Laravel уже имеет встроенную автозагрузку PSR-4: php-fig.org/psr/psr-4
heisian
1
использование PSR-4 и композитор не позволит вам включать / выключать помощников.
Пабло Эзекьель Леоне
@PabloEzequielLeone и как мне использовать его в контроллере или блейд-файле? Это выглядит как лучший вариант, если вы хотите не загружать все помощники для всех контроллеров каждый раз, но это не подходит для новичков в Laravel (как и я).
VinGarcia
12

Для пользовательских вспомогательных библиотек в моем проекте Laravel я создал папку с именем Librariesв моем Laravel/Appкаталоге и в каталоге библиотек, я создал различные файлы для разных вспомогательных библиотек.

После создания моих вспомогательных файлов я просто включаю все эти файлы в мой файл composer.json следующим образом

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

и выполнить

composer dump-autoload
Акшай Хале
источник
composer dump-autoloadи composer dumpautoloadтакже работает Infact composer duтакже будет работать ...
Акшай
10

Так как ОП попросил лучшие практики , я думаю, что здесь все еще не хватает хороших советов.

Один helpers.php файл далеко от хорошей практики. Во-первых, потому что вы смешиваете много разных видов функций, так что вы против хороших принципов кодирования. Кроме того, это может повредить не только документацию кода, но и метрики кода, такие как цикломатическая сложность , индекс ремонтопригодности и объем Холстеда. . Чем больше у вас функций, тем больше становится хуже.

Документация по коду была бы в порядке, если бы использовались такие инструменты, как phpDocumentor , но при использовании Sami он не отображал процедурные файлы . Документация по API Laravel является таким случаем - документации по вспомогательным функциям нет: https://laravel.com/api/5.4

Метрики кода можно анализировать с помощью таких инструментов, как PhpMetrics . Использование PhpMetrics версии 1.x для анализа кода платформы Laravel 5.4 даст вам очень плохие показатели CC / MI / HV как для src / Illuminate / Foundation / helpers.php, так и для src / Illuminate / Support / helpers.php файлов .

Несколько контекстных вспомогательных файлов (например, string_helpers.php , array_helpers.php и т. Д.), Безусловно, улучшат эти плохие показатели, что приведет к упрощению поддержки кода. В зависимости от используемого генератора документации кода это будет достаточно.

Это может быть улучшено путем использования вспомогательных классов со статическими методами, чтобы они могли быть контекстуализированы с использованием пространств имен. Так же, как Laravel уже делает с Illuminate\Support\Strи Illuminate\Support\Arrклассы. Это улучшает метрики кода / организацию и документацию. Псевдонимы классов могут быть использованы для облегчения их использования.

Структурирование с помощью классов делает организацию кода и документацию лучше, но, с другой стороны, мы теряем эти замечательные короткие и легко запоминающиеся глобальные функции. Мы можем еще больше улучшить этот подход, создав псевдонимы функций для этих методов статических классов. Это можно сделать вручную или динамически.

Laravel внутренне использует первый подход, объявляя функции в процедурных вспомогательных файлах, которые отображаются на методы статических классов. Это может быть не идеальной вещью, так как вам нужно переопределить все вещи (docblocks / arguments).
Я лично использую динамический подход с 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.

Пауло Фрейтас
источник
8

Вот сценарий оболочки bash, который я создал для очень быстрого создания фасадов Laravel 5.

Запустите это в вашем каталоге установки Laravel 5.

Назовите это так:

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

Пример:

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

Если запустить этот пример, он будет создавать каталоги Facadesи Providersпод "your_laravel_installation_dir / приложение / MyApp.

Он создаст следующие 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»

Запустить 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 ""
Тире
источник
8

вместо того, чтобы включать ваш собственный вспомогательный класс, вы можете добавить его в config/app.phpфайл под псевдонимами.

должен быть похож на это.

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

а затем к своему контроллеру включите помощника, используя метод 'use Helper', чтобы вы могли просто вызвать некоторые методы в своем классе помощника.

eg. Helper::some_function();

или в представлении ресурсов вы можете напрямую вызвать класс Helper.

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

Но это все еще подход разработчика, которому нужно следовать. У нас может быть другой способ решения проблем, и я просто хочу поделиться тем, что у меня есть, для начинающих.

Кеннет Сандей
источник
4

Создайте пользовательский каталог помощников. Сначала создайте каталог помощников в каталоге приложения. Создание определения класса hlper. Теперь давайте создадим простую вспомогательную функцию, которая объединит две строки. Создайте новый файл MyFuncs.php в /app/Helpers/MyFuncs.php Добавьте следующий код

<?php

namespace App\Helpers;

class MyFuncs {

    public static function full_name($first_name,$last_name) {
        return $first_name . ', '. $last_name;   
    }
}

Пространство имен App \ Helpers; определяет пространство имен помощников в пространстве имен приложений. Класс MyFuncs {…} определяет вспомогательный класс MyFuncs. public static function full_name ($ first_name, $ last_name) {…} определяет статическую функцию, которая принимает два строковых параметра и возвращает объединенную строку

Служба помощи предоставляет класс

Поставщики услуг используются для автоматической загрузки классов. Нам нужно определить поставщика услуг, который будет загружать все наши вспомогательные классы в каталог / app / Helpers.

Запустите следующую команду ремесленника:

php artisan make: провайдер 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
Мизанур Рахман
источник
4

Сначала создайте helpers.php в каталоге App \ Http. Затем добавьте следующий код в composer.json

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

Далее выполните следующую команду

composer dump-autoload

Теперь вы можете определить свою пользовательскую функцию в файле helpers.php.

ujjal
источник
3

Другой способ, который я использовал: 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());

это оно. и это работает

Dee
источник
3

Лучшая практика для написания пользовательских помощников

1) Внутри appкаталога корневого каталога проекта создайте папку с именем Helpers (просто для разделения и структурирования кода).

2) Внутри папки пишите файлы psr-4 или обычные файлы php

Если файлы PHP имеют формат psr-4, они будут загружены автоматически, в противном случае добавьте следующую строку в composer.json, который находится в корневом каталоге проекта.

Внутри autoloadключа создайте новый ключ с именем filesдля загрузки файлов во время автоматической загрузки, внутри filesобъекта добавьте путь, начиная с каталога приложения. Вот пример.

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

PS: попробуйте запустить, composer dump-autoloadесли файл не загружен.

Рея Пол Сэм
источник
3

Создать Helpers.php в приложении / Helper / 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();  ?>
Абхишек Кумар
источник
Спасибо, не могли бы вы немного расширить объяснение?
Фелипе Вальдес
2
Если класс находится в пространстве имен, добавление файла в composer.jsonнего бесполезно, поскольку автозагрузка psr-4 сделает эту работу.
Arcesilas
2

в директории начальной загрузки \ autoload.php

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

добавить этот файл

app\Helpers\function.php
panqingqiang
источник
2

**

  • Статус Помощник

** создать новый помощник

<?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'));
        }
}
Сунил
источник
0

В 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, а помощники немного лучше организованы.

Надеюсь, это кому-нибудь поможет.

Мубашар Аббас
источник
0

Здесь есть несколько отличных ответов, но я думаю, что это самый простой. В 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 разрешает конкретный класс автоматически.

omarjebari
источник