Mejores prácticas para ayudantes personalizados en Laravel 5 [cerrado]

472

Me gustaría crear funciones auxiliares para evitar repetir el código entre vistas en Laravel 5:

view.blade.php

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

Básicamente son funciones de formato de texto. ¿Dónde y cómo puedo crear un archivo con estas funciones?

Calebe Oliveira
fuente

Respuestas:

595

Cree un helpers.phparchivo en la carpeta de su aplicación y cárguelo con el compositor:

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

Después de agregar eso a su composer.jsonarchivo, ejecute el siguiente comando:

composer dump-autoload

Si no le gusta mantener su helpers.phparchivo en su appdirectorio (porque no es un archivo de clase con espacio de nombres PSR-4), puede hacer lo que hace el laravel.comsitio web: almacenarlo helpers.php en el directorio de arranque . Recuerde configurarlo en su composer.jsonarchivo:

"files": [
    "bootstrap/helpers.php"
]
Joseph Silber
fuente
86
Consejo para noobs: use este comando después de cambiar composer.json. compositor dump-autoload
Allfarid Morales García
11
@ AllfaridMoralesGarcía O tal vez solo 'Un consejo útil, ya que la respuesta no deja en claro que debes hacer esto después'.
Matt McDonald
8
Apruebo las funciones de ayuda para facilitar la escritura de vistas, pero odio cuánto se hace referencia a esta respuesta en otras respuestas. No me malinterpreten, es una buena respuesta y correcta, solo temo que las personas abusen de él y comiencen a escribir toneladas de PHP funcional mal escrito y mal organizado nuevamente.
andrewtweber
40
No entiendo este enfoque. Se supone que Composer es una herramienta para incluir bibliotecas: Laravel funcionaría perfectamente sin él y Composer sin Laravel. Esta sugerencia nos dice que creemos un archivo dentro de nuestra aplicación, que abandonemos nuestra aplicación, que vayamos a Composer, que le digamos al compositor que regrese a nuestra aplicación e incluya un archivo. Laravel maneja claramente la inclusión de archivos, ¿verdad? ¿Por qué deberíamos renunciar a la implementación nativa de Laravel y usar esta herramienta externa para incluir un archivo para nosotros, acoplando así nuestra aplicación a Composer más? ¿Es pereza o me falta algo?
dKen
66
Laravel utiliza el autocargador del compositor para saber dónde incluir todas las bibliotecas y archivos en los que se basa. Esta referenciado en bootstrap / autoload.php. Lea el comentario en ese archivo. El enfoque consiste en agregar la referencia al archivo en el composer.json, luego "volcar carga automática", que regenera el autocargador del compositor para que Laravel pueda encontrarlo. El uso de la colección de "archivos" de Composer es una buena manera de agregar bibliotecas o archivos de funciones únicos que no están perfectamente envueltos en paquetes de compositores. Es bueno tener un lugar para todas las situaciones de "por cierto tengo que incluir este archivo extraño".
Phillip Harrington
370

Clases personalizadas en Laravel 5, la manera fácil

Esta respuesta es aplicable a las clases personalizadas generales dentro de Laravel. Para obtener una respuesta más específica de Blade, consulte Directivas de Blade personalizadas en Laravel 5 .

Paso 1: cree su archivo Helpers (u otra clase personalizada) y asígnele un espacio de nombres coincidente. Escribe tu clase y método:

<?php // Code within app\Helpers\Helper.php

namespace App\Helpers;

class Helper
{
    public static function shout(string $string)
    {
        return strtoupper($string);
    }
}

Paso 2: crea un alias:

<?php // Code within config/app.php

    'aliases' => [
     ...
        'Helper' => App\Helpers\Helper::class,
     ...

Paso 3: ejecutar composer dump-autoloaden la raíz del proyecto

Paso 4: Úselo en su plantilla Blade:

<!-- Code within resources/views/template.blade.php -->

{!! Helper::shout('this is how to use autoloading correctly!!') !!}

Crédito adicional: use esta clase en cualquier lugar de su aplicación 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!!');
    }
    ...

Fuente: http://www.php-fig.org/psr/psr-4/

Por qué funciona: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/ClassLoader.php

De dónde se origina la carga automática: http://php.net/manual/en/language.oop5.autoload.php

heisian
fuente
35
Para ser claros, esta respuesta en realidad no trata con ayudantes, que son funciones de espacios de nombres globales. En cambio, fomenta la conversión de ayudantes a métodos de clase. Este es generalmente el mejor enfoque, pero en realidad no responde la pregunta que se hace aquí, por lo que otras respuestas son tan complejas en comparación.
Dan Hunsaker
1
La función auxiliar significa que también está disponible en Blade. ¿Cómo se hace esta función disponible en Blade? No puede llamar a Helper :: prettyJason (parámetros) en blade.
MaXi32
@ MaXi32, puede agregar la clase debajo de la aliasesmatriz en app/config.php: 'Helper' => App\Helpers\Helper::class, Entonces podrá llamar Helper::prettyJson();a Blade muy bien.
heisian
@DanHunsaker editó para responder directamente a la pregunta, y sigue siendo el mismo enfoque simple. También puede escribir sus propias directivas de blade personalizadas: stackoverflow.com/questions/28290332/…
heisian
1
Sí, revisé el marco una vez y descubrí dónde atraían a los ayudantes. Y nuevamente, estoy completamente de acuerdo en que los métodos de clases estáticas con espacios de nombres son mucho más limpios que lo que se solicita, o se recomienda, la mayoría de las veces. El hecho es que los ayudantes no son realmente The Laravel Way en primer lugar, sino más bien un remanente de CodeIgniter 2.x que aún no se ha eliminado. Entonces, mi pedantería sobre este enfoque que no responde al OP exactamente como se le preguntó es más un intento de resaltar el hecho de que no obtiene ayudantes, sino algo mejor.
Dan Hunsaker
315

mi pensamiento inicial fue la carga automática del compositor también, pero no me pareció muy Laravel 5ish. L5 hace un uso intensivo de los proveedores de servicios, que son los que inician su aplicación.

Para comenzar, creé una carpeta en mi appdirectorio llamada Helpers. Luego, dentro de la Helperscarpeta, agregué archivos para las funciones que quería agregar. Tener una carpeta con varios archivos nos permite evitar un archivo grande que se vuelve demasiado largo e inmanejable.

Luego creé un HelperServiceProvider.phpejecutando el comando artesanal:

artisan make:provider HelperServiceProvider

Dentro del registermétodo agregué este fragmento

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

por último, registre el proveedor de servicios en su config/app.phpen la matriz de proveedores

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

ahora cualquier archivo en su Helpersdirectorio está cargado y listo para usar.

ACTUALIZACIÓN 2016-02-22

Aquí hay muchas buenas opciones, pero si mi respuesta funciona para usted, seguí adelante e hice un paquete para incluir ayudantes de esta manera. Puede utilizar el paquete como inspiración o descargarlo también con Composer. Tiene algunos ayudantes integrados que uso a menudo (pero que están inactivos por defecto) y le permite crear sus propios ayudantes personalizados con un simple generador Artisan. También aborda la sugerencia que tenía un respondedor de usar un mapeador y le permite definir explícitamente los ayudantes personalizados para cargar, o por defecto, cargar automáticamente todos los archivos PHP en su directorio auxiliar. Comentarios y relaciones públicas son muy apreciados!

composer require browner12/helpers

Github: browner12 / helpers

Andrew Brown
fuente
29
Para las personas que solo tienen algunas funciones que necesitan agregar, la carga automática del compositor está perfectamente bien, pero para aquellos de nosotros que pueden tener muchas funciones auxiliares, la organización de múltiples archivos es imprescindible. Esta solución es esencialmente lo que hice en L4, excepto que registré los archivos en mi start.phparchivo (que no fue genial, pero cumplió su propósito por el momento). ¿Tienes otra sugerencia para cargar varios archivos?
Andrew Brown
77
Si tiene varios archivos, agréguelos a su archivo composer.json. Agregar incluso 5-10 líneas allí tiene mucho más sentido que lo que tienes aquí.
Joseph Silber
22
Creo que esta técnica tiene mucho mérito. Es elegante y eficiente porque no tiene que recordar meterse con el archivo composer.json cada vez que crea un archivo auxiliar.
impeto
8
Muy buena solución. Lo único que no estoy de acuerdo es la forma en que agrega los archivos, creo que debería ser un mapeador, donde agregamos el nombre del archivo que queremos cargar. ¡Piensa en los errores! Si solo hay un ayudante en uno de los archivos que está fallando, entonces debe eliminarlos todos o hacer que el sitio se rompa hasta que lo resuelva.
Pablo Ezequiel Leone
3
¿Utiliza el espacio de nombres App \ Providers? Cómo llamo a ese ayudante desde el controlador y la vista. Lo siento, novata pregunta.
Cengkaruk
79

Esto es lo que sugiere JeffreyWayesta Discusión de Laracasts .

  1. Dentro de su app/Httpdirectorio, cree un helpers.phparchivo y agregue sus funciones.
  2. Dentro composer.json, en el autoloadbloque, agregue "files": ["app/Http/helpers.php"].
  3. Ejecutar composer dump-autoload.
itsazzad
fuente
15
Los ayudantes pueden no ser solo HTTP. app/helpers.phpo app/Helpers/parece ser un lugar mejor.
Sepehr
1
¿Qué sucede si estamos en un servidor compartido y no tenemos la opción de usar composer dump-autoload ?
user3201500
@ user3201500 esa es otra pregunta y es posible que deba hacerlo manualmente si desea seguir la respuesta anterior. O puede elegir entre otras respuestas. Y reflejar de forma manual la composer dump-autoloadpuede seguir esto: developed.be/2014/08/29/composer-dump-autoload-laravel
itsazzad
55

Habiendo examinado una variedad de respuestas en SO y Google, todavía no pude encontrar un enfoque óptimo. La mayoría de las respuestas sugieren que abandonemos la aplicación y confiemos en la herramienta de terceros Composer para hacer el trabajo, pero no estoy convencido de que sea conveniente acoplar una herramienta solo para incluir un archivo.

La respuesta de Andrew Brown fue lo más parecido a cómo creo que debería abordarse, pero (al menos en 5.1), el paso del proveedor de servicios es innecesario. La respuesta de Heisian destaca el uso de lo PSR-4que nos acerca un paso más. Aquí está mi implementación final para ayudantes en vistas:

Primero, cree un archivo auxiliar en cualquier lugar de su directorio de aplicaciones, con un espacio de nombres:

namespace App\Helpers;

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

A continuación, alias su clase en config\app.php, en la aliasesmatriz:

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

Y eso debería ser todo lo que necesitas hacer. PSR-4y el alias debe exponer el ayudante a sus vistas, por lo que en su vista, si escribe:

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

Debería generar:

<strong>Bob?! Is that you?!</strong>
dKen
fuente
Gracias por publicar esto. como señaló @ Dan-Hunsaker en mi solución, todavía no hemos terminado con una función de espacio de nombres global, es decir, poder escribir de manera simple {!! bob() !!}. vamos a buscar un poco más y ver si eso es posible
heisian
1
Lo he pensado más e intentar hacer algo bob()verdaderamente global no sería una buena idea . Los espacios de nombres están ahí por una razón y no deberíamos llamar bob()junto con las funciones básicas de PHP. Agregaré su bit de alias a mi código, ¡gracias!
Heisian
1
Creo que este es el mejor de todos
Jimmy Obonyo Abor
¿Por qué hay extends Helper? No me parece necesario.
bernie
@bernie @ user3201500 Lo siento equipo, tuve mi propia clase de ayuda base de la que heredan todos mis ayudantes; De extends Helperhecho, no es necesario. Gracias por el aviso.
dKen
32

Directivas de cuchillas personalizadas en Laravel 5

¡Sí, hay otra forma de hacer esto!

Paso 1: Registre una directiva Blade personalizada:

<?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>';
         });
     }
    ...

Paso 2: usa tu directiva Blade personalizada:

<!-- // code in resources/views/view.blade.php -->

@shout('this is my custom blade directive!!')
<br />
@customLink

Salidas:

¡ESTA ES MI DIRECTIVA DE CUCHILLA PERSONALIZADA!
Enlace personalizado


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

Lectura adicional: https://mattstauffer.co/blog/custom-conditionals-with-laravels-blade-directives


Si desea aprender cómo crear clases personalizadas que pueda usar en cualquier lugar , consulte Clases personalizadas en Laravel 5, la manera fácil

heisian
fuente
Esto debería marcarse como la mejor respuesta, porque la pregunta era "para evitar repetir el código entre algunas vistas". La palabra clave es VIEWS. :)
Aleksandrs
23

Este es mi archivo 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;
            }
        }
    }
}

Debe crear una carpeta llamada Helpersdebajo de la appcarpeta, luego crear un archivo llamado whatever.phpdentro y agregar la cadena whateverdentro de la matriz $ helpers.

¡Hecho!

Editar

Ya no estoy usando esta opción, actualmente estoy usando Composer para cargar archivos estáticos como ayudantes.

Puede agregar los ayudantes directamente en:

...
"autoload": {
    "files": [
        "app/helpers/my_helper.php",
        ...
    ]
},
...
Pablo Ezequiel Leone
fuente
¿Hay alguna otra razón además del rendimiento para crear un mapeador en lugar de cargar todos los archivos en el directorio glob()como escribió Andrew Brown? Si desea poder especificar los archivos que desea incluir, ¿por qué no especificar los archivos en la composer.jsoncarga automática como escribió Joseph Silber? ¿Por qué prefieres esta solución? No digo que sea una mala solución, solo tengo curiosidad.
Pelmered
3
Es más fácil, con un enfoque mapeado, habilitar / deshabilitar selectivamente los ayudantes si, por ejemplo, uno de los archivos de ayuda contiene un error de ruptura. Dicho esto, la asignación de archivos en un proveedor de servicios no es muy diferente de hacerlo, composer.jsonexcepto por dos puntos: primero, mantiene el mapa dentro de la aplicación en sí, en lugar de un archivo de metadatos; segundo, no requiere que vuelva a ejecutar composer dump-autoloadcada vez que cambia la lista de archivos para cargar.
Dan Hunsaker
No es necesario includeo require, Laravel ya tiene una carga automática de PSR-4 incorporada
heisian
1
usando PSR-4 y el compositor no le permitirán encender / apagar ayudantes.
Pablo Ezequiel Leone
@PabloEzequielLeone y ¿cómo lo usaría dentro de un controlador o un archivo Blade? Esta parece ser la mejor opción si le preocupa no cargar todos los ayudantes para todos los controladores cada vez, pero no es bueno para los principiantes en Laravel (como yo).
VinGarcia
12

Para las bibliotecas auxiliares personalizadas en mi proyecto Laravel, he creado una carpeta con nombre Librariesen mi Laravel/Appdirectorio y dentro del directorio de bibliotecas, he creado varios archivos para diferentes bibliotecas auxiliares.

Después de crear mis archivos auxiliares, simplemente incluyo todos esos archivos en mi archivo composer.json como este

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

y ejecutar

composer dump-autoload
Akshay Khale
fuente
composer dump-autoloady composer dumpautoloadtambién funciona de hecho composer dutambién funcionará ...
Akshay Khale
10

Como OP solicitó las mejores prácticas , creo que todavía nos faltan algunos buenos consejos aquí.

Un solo archivo helpers.php está lejos de ser una buena práctica. En primer lugar, porque mezclas muchos tipos diferentes de funciones, por lo que estás en contra de los buenos principios de codificación. Además, esto podría dañar no solo la documentación del código, sino también las métricas del código como la Complejidad Ciclomática , el Índice de Mantenibilidad y el Volumen de Halstead . Cuantas más funciones tenga, más empeorará.

Documentación de código no estaría mal uso de herramientas como phpDocumentor , pero utilizando Sami que no va a hacer que los ficheros de procedimiento . La documentación de Laravel API es un caso así: no hay documentación de funciones auxiliares: https://laravel.com/api/5.4

Las métricas de código se pueden analizar con herramientas como PhpMetrics . El uso de PhpMetrics versión 1.x para analizar el código marco de Laravel 5.4 le dará muy malas métricas CC / MI / HV para src / Illuminate / Foundation / helpers.php y src / Illuminate / Support / helpers.php archivos .

Múltiples archivos auxiliares contextuales (por ejemplo , string_helpers.php , array_helpers.php , etc.) ciertamente mejorarían esas métricas malas, lo que resultaría en un código más fácil de mantener. Dependiendo del generador de documentación de código utilizado, esto sería lo suficientemente bueno.

Se puede mejorar aún más mediante el uso de clases auxiliares con métodos estáticos para que puedan contextualizarse utilizando espacios de nombres. Al igual que Laravel ya lo hace con Illuminate\Support\Stry las Illuminate\Support\Arrclases. Esto mejora tanto la métrica / organización del código como la documentación. Los alias de clase podrían usarse para hacerlos más fáciles de usar.

La estructuración con clases mejora la organización y la documentación del código, pero, por otro lado, terminamos perdiendo esas funciones globales breves y fáciles de recordar. Podemos mejorar aún más ese enfoque creando alias de función para esos métodos de clases estáticas. Esto se puede hacer de forma manual o dinámica.

Laravel usa internamente el primer enfoque declarando funciones en los archivos auxiliares de procedimiento que se asignan a los métodos de clases estáticas. Esto podría no ser lo ideal, ya que necesita volver a declarar todas las cosas (bloques de documentos / argumentos).
Personalmente uso un enfoque dinámico con una HelperServiceProviderclase que crea esas funciones en el tiempo de ejecución:

<?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()
    {
        //
    }
}

Se puede decir que esto se debe a la ingeniería, pero no lo creo. Funciona bastante bien y, al contrario de lo que cabría esperar, no cuesta un tiempo de ejecución relevante al menos cuando se usa PHP 7.x.

Paulo Freitas
fuente
8

Aquí hay un script de shell bash que creé para hacer las fachadas de Laravel 5 muy rápidamente.

Ejecute esto en su directorio de instalación de Laravel 5.

Llámalo así:

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

Ejemplo:

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

Si ejecuta ese ejemplo, creará los directorios Facadesy Providersdebajo de 'your_laravel_installation_dir / app / MyApp'.

Creará los siguientes 3 archivos y también los enviará a la pantalla:

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

Una vez hecho esto, mostrará un mensaje similar al siguiente:

===========================
    Finished
===========================

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

Actualice la lista de proveedores y alias en 'config / app.php'

correr composer -o dumpautoload

El "./app/MyApp/Facades/Helper.php" originalmente se verá así:

<?php

namespace App\MyApp\Facades;


class Helper
{
    //
}

Ahora solo agregue sus métodos en "./app/MyApp/Facades/Helper.php".

Así es como se ve "./app/MyApp/Facades/Helper.php" después de agregar una función de ayuda.

<?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) !!}

Esta función espera un patrón y puede aceptar un segundo argumento booleano opcional.

Si la URL actual coincide con el patrón que se le pasó, generará 'active' (o 'class = "active"' si agrega 'true' como segundo argumento a la llamada a la función).

Lo uso para resaltar el menú que está activo.

A continuación se muestra el código fuente de mi script. Espero que lo encuentre útil y avíseme si tiene algún problema.

#!/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 ""
Guión
fuente
8

en lugar de incluir su clase auxiliar personalizada, en realidad puede agregar a su config/app.phparchivo con alias.

Debería verse así.

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

y luego a su Controlador, incluya el Helper usando el método 'use Helper' para que simplemente pueda llamar a algunos de los métodos en su clase Helper.

eg. Helper::some_function();

o en la vista de recursos ya puede llamar directamente a la clase Helper.

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

Pero este sigue siendo el enfoque de estilo de codificación de desarrollador a seguir. Es posible que tengamos una forma diferente de resolver problemas, y solo quiero compartir lo que tengo también para principiantes.

Domingo de Kenneth
fuente
4

Crear directorio de ayudantes personalizado: Primero cree el directorio de ayudantes en el directorio de la aplicación. Crear definición de clase hlper: ahora creemos una función auxiliar simple que concatene dos cadenas. Cree un nuevo archivo MyFuncs.php en /app/Helpers/MyFuncs.php Agregue el siguiente código

<?php

namespace App\Helpers;

class MyFuncs {

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

App de espacio de nombres \ Helpers; define el espacio de nombres Helpers en el espacio de nombres de la aplicación. La clase MyFuncs {…} define la clase auxiliar MyFuncs. public static function full_name ($ first_name, $ last_name) {…} define una función estática que acepta dos parámetros de cadena y devuelve una cadena concatenada

El servicio de ayuda proporciona clase

Los proveedores de servicios se utilizan para cargar automáticamente las clases. Tendremos que definir un proveedor de servicios que cargue todas nuestras clases de ayuda en el directorio / app / Helpers.

Ejecute el siguiente comando artesanal:

php artisan make: proveedor HelperServiceProvider

El archivo se creará en /app/Providers/HelperServiceProvider.php

Open /app/Providers/HelperServiceProvider.php

Agregue el siguiente código:

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

AQUÍ,

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.

Ahora necesitamos registrar el HelperServiceProvider y crear un alias para nuestros ayudantes.

Abrir /config/app.phparchivo

Localice la variable de matriz de proveedores

Agregue la siguiente línea

App\Providers\HelperServiceProvider::class,

Localice la variable de matriz de alias

Agregue la siguiente línea

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

Guarde los cambios con nuestro ayudante personalizado

Crearemos una ruta que llamará a nuestra función auxiliar personalizada Abrir /app/routes.php

Agregue la siguiente definición de ruta

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

AQUÍ,

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

Primero cree helpers.php dentro del directorio App \ Http. Luego agregue el siguiente código dentro del composer.json

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

Luego ejecute el siguiente comando

composer dump-autoload

Ahora puede definir su función personalizada dentro del archivo helpers.php.

ujjal
fuente
3

Otra forma que utilicé fue: 1) creó un archivo en app \ FolderName \ fileName.php y tenía este código dentro, es decir

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

2) Después de eso en nuestra cuchilla

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

Eso es. y funciona

Dee
fuente
3

La mejor práctica para escribir ayudantes personalizados es

1) Dentro del appdirectorio de la raíz del proyecto, cree una carpeta llamada Helpers (solo para separar y estructurar el código).

2) Dentro de la carpeta escriba archivos psr-4 o archivos php normales

Si los archivos PHP tienen el formato psr-4, se cargarán automáticamente; de ​​lo contrario, agregue la siguiente línea en composer.json, que se encuentra dentro del directorio raíz del proyecto.

Dentro de la autoloadclave, cree una nueva clave llamada filespara cargar archivos en el momento de la carga automática, dentro del filesobjeto agregue la ruta a partir del directorio de la aplicación. Aquí hay un ejemplo.

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

PD: intente ejecutar composer dump-autoloadsi el archivo no se carga.

Reiah Paul Sam
fuente
3

Cree Helpers.php en la aplicación / Helper / Helpers.php

namespace App\Helper
class Helpers
{


}

Agregar compositor y actualización de compositor

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

utilizar en controlador

use App \ Helper \ Helpers

usar en vista cambiar en el archivo config-> app.php

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

llamar a la vista

<?php echo Helpers::function_name();  ?>
abhishek kumar
fuente
Gracias, ¿le importaría ampliar un poco su explicación?
Felipe Valdés
2
Si la clase tiene un espacio de nombres, agregar el archivo composer.jsones inútil, ya que la carga automática de psr-4 hará el trabajo.
Arcesilas
2

en dir bootstrap \ autoload.php

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

agrega este archivo

app\Helpers\function.php
panqingqiang
fuente
2

** **

  • Ayudante de estado

** crear nuevo ayudante

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

Úselo para el controlador y cualquier archivo de vista

use App\Helpers\StatusHelper;

class ExampleController extends Controller
{
        public function index()
        {
            $statusList = StatusHelper::getStatusesList();

            return view('example.index', compact('statusList'));
        }
}
Sunil
fuente
0

En laravel 5.3 y superior, el equipo de laravel movió todos los archivos de procedimiento ( routes.php) fuera del app/directorio, y toda la app/carpeta se psr-4carga automáticamente. La respuesta aceptada funcionará en este caso, pero no me parece correcta.

Entonces, lo que hice fue crear un helpers/directorio en la raíz de mi proyecto y poner los archivos auxiliares dentro de eso, y en mi composer.jsonarchivo hice esto:

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

De esta manera, mi app/directorio sigue siendo uno con carga automática de psr-4, y los ayudantes están un poco mejor organizados.

Espero que esto ayude a alguien.

Mubashar Abbas
fuente
0

Aquí hay algunas respuestas geniales, pero creo que esta es la más simple. En Laravel 5.4 (y probablemente también en versiones anteriores) puede crear una clase en algún lugar conveniente para usted, por ejemplo, App / Libraries / Helper.php

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

Luego, simplemente puede llamarlo en su plantilla Blade de esta manera:

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

Si no desea utilizar @inject, simplemente haga que la función 'uppercasePara' sea estática e inserte la llamada en su plantilla Blade de esta manera:

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

No hay necesidad de alias. Laravel resuelve la clase concreta automáticamente.

omarjebari
fuente