Best Practices für benutzerdefinierte Helfer in Laravel 5 [geschlossen]

472

Ich möchte Hilfsfunktionen erstellen, um zu vermeiden, dass Code zwischen Ansichten in Laravel 5 wiederholt wird:

view.blade.php

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

Sie sind im Grunde Textformatierungsfunktionen. Wo und wie kann ich mit diesen Funktionen eine Datei erstellen?

Calebe Oliveira
quelle

Antworten:

595

Erstellen Sie eine helpers.phpDatei in Ihrem App-Ordner und laden Sie sie mit Composer hoch:

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

composer.jsonFühren Sie nach dem Hinzufügen zu Ihrer Datei den folgenden Befehl aus:

composer dump-autoload

Wenn Sie Ihre helpers.phpDatei nicht in Ihrem appVerzeichnis behalten möchten (da es sich nicht um eine PSR-4-Klassendatei mit Namespace handelt), können Sie das tun, was die laravel.comWebsite tut: Speichern Sie die Datei helpers.php im Bootstrap-Verzeichnis . Denken Sie daran, es in Ihrer composer.jsonDatei festzulegen:

"files": [
    "bootstrap/helpers.php"
]
Joseph Silber
quelle
85
Tipp für Noobs: Verwenden Sie diesen Befehl, nachdem Sie composer.json geändert haben. Komponist Dump-Autoload
Allfarid Morales García
11
@ AllfaridMoralesGarcía Oder vielleicht nur 'Ein nützlicher Tipp, da die Antwort nicht klar macht, dass Sie dies später tun müssen'.
Matt McDonald
8
Ich bin mit Hilfsfunktionen einverstanden, um das Schreiben von Ansichten zu vereinfachen, aber ich hasse es, wie oft in anderen Antworten auf diese Antwort verwiesen wird. Versteh mich nicht falsch, es ist eine gute Antwort und richtig, ich befürchte nur, dass die Leute es missbrauchen und wieder anfangen, Tonnen von schlecht geschriebenem, schlecht organisiertem funktionierendem PHP zu schreiben.
Andrewwweber
39
Ich verstehe diesen Ansatz nicht. Composer soll ein Werkzeug sein, um Bibliotheken einzuschließen: Laravel würde ohne es perfekt funktionieren, und Composer ohne Laravel. Dieser Vorschlag fordert uns auf, eine Datei in unserer App zu erstellen, unsere App zu verlassen, zu Composer zu wechseln und den Composer anzuweisen, wieder in unsere App zurückzukehren und eine Datei einzuschließen. Laravel kümmert sich eindeutig um die Aufnahme von Dateien, oder? Warum sollten wir auf die native Implementierung von Laravel verzichten und dieses externe Tool verwenden, um eine Datei für uns einzuschließen und so unsere Anwendung stärker an Composer zu koppeln? Ist es Faulheit oder fehlt mir etwas?
dKen
6
Laravel verwendet den Autoloader des Komponisten, um zu wissen, wo alle Bibliotheken und Dateien enthalten sein sollen, auf die er sich stützt. Dies wird in bootstrap / autoload.php angegeben. Lesen Sie den Kommentar in dieser Datei. Der Ansatz besteht darin, den Verweis auf die Datei in die Datei composer.json einzufügen und dann "Autoload sichern", wodurch der Autoloader des Komponisten neu generiert wird, damit Laravel ihn finden kann. Die Verwendung der "files" -Sammlung von Composer ist eine gute Möglichkeit, Bibliotheken oder einmalige Funktionsdateien hinzuzufügen, die nicht ordentlich in Composer-Paketen verpackt sind. Es ist schön, einen Platz für all die Situationen zu haben, in denen "übrigens ich diese eine seltsame Datei einschließen muss".
Phillip Harrington
370

Benutzerdefinierte Klassen in Laravel 5, der einfache Weg

Diese Antwort gilt für allgemeine benutzerdefinierte Klassen in Laravel. Eine weitere Blade-spezifische Antwort finden Sie unter Benutzerdefinierte Blade-Anweisungen in Laravel 5 .

Schritt 1: Erstellen Sie Ihre Helferdatei (oder eine andere benutzerdefinierte Klasse) und geben Sie ihr einen passenden Namespace. Schreiben Sie Ihre Klasse und Methode:

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

namespace App\Helpers;

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

Schritt 2: Erstellen Sie einen Alias:

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

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

Schritt 3: Führen Sie composer dump-autoloaddas Projektstammverzeichnis aus

Schritt 4: Verwenden Sie es in Ihrer Blade-Vorlage:

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

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

Zusätzliches Guthaben: Verwenden Sie diese Klasse an einer beliebigen Stelle in Ihrer Laravel-App:

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

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

Warum es funktioniert: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/ClassLoader.php

Woher das automatische Laden stammt von: http://php.net/manual/en/language.oop5.autoload.php

heisian
quelle
35
Um es klar auszudrücken, diese Antwort befasst sich nicht mit Helfern, bei denen es sich um Funktionen mit globalem Namespace handelt. Stattdessen wird empfohlen, Helfer in Klassenmethoden umzuwandeln. Dies ist im Allgemeinen der beste Ansatz, beantwortet jedoch nicht die hier gestellte Frage, weshalb andere Antworten im Vergleich so komplex sind.
Dan Hunsaker
1
Funktionshilfe bedeutet, dass sie auch in Blade verfügbar ist. Wie stellen Sie diese Funktion in Blade zur Verfügung? Sie können Helper :: prettyJason (Parameter) in Blade nicht aufrufen.
MaXi32
@ MaXi32 Sie könnten die Klasse unter dem aliasesArray hinzufügen in app/config.php: 'Helper' => App\Helpers\Helper::class, Dann könnten Sie Helper::prettyJson();Blade ganz gut aufrufen .
Heisian
@DanHunsaker bearbeitet, um die Frage direkt zu beantworten, und es ist immer noch der gleiche einfache Ansatz. Sie können auch einfach Ihre eigenen benutzerdefinierten Blade-Anweisungen schreiben: stackoverflow.com/questions/28290332/…
heisian
1
Ja, ich habe mich einmal im Framework umgesehen und herausgefunden, wo sie die Helfer hineingezogen haben. Und wieder stimme ich voll und ganz zu, dass Methoden für statische Klassen mit Namespace viel besser passen als das, was die meiste Zeit angefordert oder empfohlen wird. Tatsache ist, dass Helfer nicht in erster Linie The Laravel Way sind, sondern ein Überbleibsel von CodeIgniter 2.x, das immer noch nicht ausläuft. Meine Pedanterie über diesen Ansatz, der das OP nicht genau wie gewünscht beantwortet, ist eher ein Versuch, die Tatsache hervorzuheben, dass Sie keine Helfer bekommen, sondern etwas Besseres.
Dan Hunsaker
315

Mein erster Gedanke war auch das Autoload des Komponisten, aber es fühlte sich für mich nicht sehr laravelisch an. L5 nutzt Service Provider in hohem Maße. Sie sind das, was Ihre Anwendung bootstraps.

Zu Beginn habe ich in meinem appVerzeichnis einen Ordner namens erstellt Helpers. Dann innerhalb derHelpers ich Ordners Dateien für Funktionen hinzugefügt, ich hinzufügen wollte. Wenn wir einen Ordner mit mehreren Dateien haben, können wir vermeiden, dass eine große Datei zu lang und nicht mehr verwaltbar ist.

Als nächstes habe ich eine erstellt, HelperServiceProvider.phpindem ich den handwerklichen Befehl ausgeführt habe:

artisan make:provider HelperServiceProvider

Innerhalb der registerMethode habe ich dieses Snippet hinzugefügt

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

Zuletzt registrieren Sie den Dienstanbieter in Ihrem config/app.phpim Anbieter-Array

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

Jetzt jede Datei in Ihrem Helpers Verzeichnis geladen und ist einsatzbereit.

UPDATE 22.02.2016

Hier gibt es viele gute Optionen, aber wenn meine Antwort für Sie funktioniert, habe ich ein Paket erstellt, um auf diese Weise Helfer einzubeziehen. Sie können das Paket entweder als Inspiration verwenden oder es auch mit Composer herunterladen. Es hat einige eingebaute Helfer, die ich oft benutze (die aber standardmäßig alle inaktiv sind) und ermöglicht es Ihnen, Ihre eigenen benutzerdefinierten Helfer mit einem einfachen Artisan-Generator zu erstellen. Es behandelt auch den Vorschlag eines Responders, einen Mapper zu verwenden, und ermöglicht es Ihnen, die benutzerdefinierten Helfer, die geladen werden sollen, explizit zu definieren oder standardmäßig automatisch alle PHP-Dateien in Ihr Hilfsverzeichnis zu laden. Feedback und PRs werden sehr geschätzt!

composer require browner12/helpers

Github: browner12 / helfer

Andrew Brown
quelle
29
Für Leute, die nur wenige Funktionen haben, die sie hinzufügen müssen, ist das automatische Laden des Komponisten vollkommen in Ordnung, aber für diejenigen von uns, die möglicherweise viele Hilfsfunktionen haben, ist die Organisation mehrerer Dateien ein Muss. Diese Lösung ist im Wesentlichen das, was ich in L4 gemacht habe, außer dass ich die Dateien in meiner start.phpDatei registriert habe (was nicht großartig war, aber seinen Zweck für die Zeit erfüllt hat). Haben Sie einen weiteren Vorschlag zum Laden mehrerer Dateien?
Andrew Brown
7
Wenn Sie mehrere Dateien haben, fügen Sie diese alle zu Ihrer Datei composer.json hinzu. Hinzufügen sogar 5-10 Linien es macht Weg mehr Sinn als das, was Sie hier haben.
Joseph Silber
22
Ich denke, diese Technik hat viel Verdienst. Es ist elegant und effizient, da Sie nicht jedes Mal, wenn Sie eine Hilfsdatei erstellen, daran denken müssen, mit der Datei composer.json herumzuspielen.
Impeto
8
Wirklich gute Lösung. Das einzige, was ich nicht einverstanden bin, ist die Art und Weise, wie Sie die Dateien hinzufügen. Ich denke, es sollte stattdessen ein Mapper sein, bei dem wir den Namen der Datei hinzufügen, die wir laden möchten. Denken Sie an Fehler! Wenn in einer der fehlgeschlagenen Dateien nur ein Helfer vorhanden ist, sollten Sie alle entfernen oder die Site beschädigen, bis Sie sie behoben haben.
Pablo Ezequiel Leone
3
Verwenden Sie den Namespace App \ Providers? Wie ich diesen Helfer von Controller und Ansicht nenne. Entschuldigung, keine Frage.
Cengkaruk
79

Dies wird JeffreyWayin dieser Laracasts-Diskussion vorgeschlagen .

  1. app/HttpErstellen Sie in Ihrem Verzeichnis einehelpers.php Datei und fügen Sie Ihre Funktionen hinzu.
  2. Fügen Sie composer.jsoninnerhalb des autoloadBlocks hinzu"files": ["app/Http/helpers.php"] .
  3. Ausführen composer dump-autoload.
itsazzad
quelle
15
Die Helfer sind möglicherweise nicht nur HTTP. app/helpers.phpoder app/Helpers/scheint ein besserer Ort zu sein.
September
1
Was ist, wenn wir uns auf einem gemeinsam genutzten Server befinden und keine Option zur Verwendung haben composer dump-autoload ?
user3201500
@ user3201500 das ist eine andere Frage, die Sie möglicherweise manuell stellen müssen, wenn Sie der obigen Antwort folgen möchten. Oder Sie können aus anderen Antworten wählen. Und um das manuell composer dump-autoload
wiederzugeben,
55

Nachdem ich eine Vielzahl von Antworten auf SO und Google durchgesehen hatte, konnte ich immer noch keinen optimalen Ansatz finden. Die meisten Antworten deuten darauf hin, dass wir die Anwendung verlassen und uns bei der Ausführung auf das Tool Composer eines Drittanbieters verlassen. Ich bin jedoch nicht davon überzeugt, dass die Kopplung an ein Tool nur zum Einfügen einer Datei sinnvoll ist.

Die Antwort von Andrew Brown kam meiner Meinung nach am nächsten, aber (zumindest in 5.1) ist der Schritt des Dienstanbieters nicht erforderlich. Heisians Antwort hebt hervor, wessen Verwendung PSR-4uns einen Schritt näher bringt. Hier ist meine endgültige Implementierung für Helfer in Ansichten:

Erstellen Sie zunächst eine beliebige Hilfedatei in Ihrem Apps-Verzeichnis mit einem Namespace:

namespace App\Helpers;

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

Als nächstes alias Ihre Klasse in config\app.php, im aliasesArray:

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

Und das sollte alles sein, was Sie tun müssen. PSR-4und der Alias ​​sollte den Helfer Ihren Ansichten aussetzen, also in Ihrer Ansicht, wenn Sie Folgendes eingeben:

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

Es sollte Folgendes ausgeben:

<strong>Bob?! Is that you?!</strong>
dKen
quelle
Danke, dass du das gepostet hast. Wie @ Dan-Hunsaker in meiner Lösung betonte, haben wir immer noch keine Funktion mit globalem Namensraum erhalten, dh wir können einfach schreiben {!! bob() !!}.
Ich
1
Ich habe mehr darüber nachgedacht und zu versuchen, bob()wirklich global zu werden, wäre keine kluge Sache. Namespaces gibt es aus einem Grund und wir sollten nicht bob()neben Basis-PHP-Funktionen aufrufen . Ich werde Ihr Aliasing-Bit zu meinem Code hinzufügen - danke!
Heisian
1
Ich finde das das Beste von allem
Jimmy Obonyo Abor
Warum gibt es extends Helper? Es scheint mir nicht notwendig zu sein.
Bernie
@bernie @ user3201500 Sorry Team, ich hatte meine eigene Basis-Helferklasse, von der alle meine Helfer erben. das extends Helperist ja nicht nötig. Danke für die Warnung.
dKen
31

Benutzerdefinierte Blade-Richtlinien in Laravel 5

Ja, da ist noch einer Weg!

Schritt 1: Registrieren Sie eine benutzerdefinierte Blade-Direktive:

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

Schritt 2: Verwenden Sie Ihre benutzerdefinierte Blade-Direktive:

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

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

Ausgänge:

DAS IST MEINE BENUTZERDEFINIERTE KLINGENRICHTLINIE !!
Benutzerdefinierten Link


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

Zusätzliche Lektüre: https://mattstauffer.co/blog/custom-conditionals-with-laravels-blade-directives


Wenn Sie lernen möchten, wie Sie am besten benutzerdefinierte Klassen erstellen, die Sie überall verwenden können, lesen Sie Benutzerdefinierte Klassen in Laravel 5, auf einfache Weise

heisian
quelle
Dies sollte als die beste Antwort markiert werden, da die Frage lautete "um zu vermeiden, dass Code zwischen einigen Ansichten wiederholt wird". Schlüsselwort ist ANSICHTEN. :)
Aleksandrs
23

Dies ist meine HelpersProvider.php-Datei:

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

Sie sollten einen Ordner erstellen, der Helpersunter dem Ordner aufgerufen wird app, dann eine Datei mit dem Namen whatever.phpinside erstellen und die Zeichenfolge whateverim Array $ helpers hinzufügen .

Erledigt!

Bearbeiten

Ich verwende diese Option nicht mehr. Derzeit verwende ich Composer, um statische Dateien wie Helfer zu laden.

Sie können die Helfer direkt hinzufügen unter:

...
"autoload": {
    "files": [
        "app/helpers/my_helper.php",
        ...
    ]
},
...
Pablo Ezequiel Leone
quelle
Gibt es andere Gründe als die Leistung, einen Mapper zu erstellen, anstatt alle Dateien im Verzeichnis zu laden, mit denen glob()Andrew Brown geschrieben hat? Wenn Sie in der Lage sein möchten, die Dateien anzugeben, die Sie einschließen möchten, geben Sie die Dateien an, composer.jsonum sie automatisch zu laden, wie Joseph Silber es geschrieben hat. Warum bevorzugen Sie diese Lösung? Ich sage nicht, dass dies eine schlechte Lösung ist, ich bin nur neugierig.
Pelmered
3
Mit einem zugeordneten Ansatz ist es einfacher, Helfer selektiv zu aktivieren / deaktivieren, wenn beispielsweise eine der Hilfsdateien einen Fehler enthält. Das Zuordnen von Dateien in einem Dienstanbieter unterscheidet sich jedoch composer.jsonnur durch zwei Punkte. Erstens wird die Zuordnung in der Anwendung selbst und nicht in einer Metadatendatei gespeichert. Zweitens müssen Sie nicht composer dump-autoloadjedes Mal neu ausführen, wenn Sie die Liste der zu ladenden Dateien ändern.
Dan Hunsaker
Keine Notwendigkeit für includeoder require, Laravel hat bereits PSR-4 Autoloading eingebaut
heisian
1
Wenn Sie PSR-4 und Composer verwenden, können Sie die Helfer nicht ein- und ausschalten.
Pablo Ezequiel Leone
@PabloEzequielLeone und wie würde ich es in einem Controller oder einer Blade-Datei verwenden? Dies scheint die beste Option zu sein, wenn Sie nicht jedes Mal alle Helfer für alle Controller laden möchten, aber nicht gut für Anfänger in Laravel (wie ich).
VinGarcia
12

Für benutzerdefinierte Hilfsbibliotheken in meinem Laravel-Projekt habe ich einen Ordner mit dem Namen Librariesin meinem erstelltLaravel/App Verzeichnis erstellt und im Verzeichnis Bibliotheken verschiedene Dateien für verschiedene Hilfsbibliotheken erstellt.

Nachdem ich meine Hilfsdateien erstellt habe, füge ich einfach alle diese Dateien wie folgt in meine composer.json- Datei ein

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

und ausführen

composer dump-autoload
Akshay Khale
quelle
composer dump-autoloadund composer dumpautoloadfunktioniert auch infact composer duwird auch funktionieren ...
Akshay Khale
10

Da fragte OP nach Best Practices , fehlen uns hier noch einige gute Ratschläge.

Eine einzelne helpers.php- Datei ist keine gute Praxis. Erstens, weil Sie viele verschiedene Arten von Funktionen mischen und somit gegen die guten Codierungsprinzipien sind. Darüber hinaus könnte dies nicht nur die Codedokumentation, sondern auch die Codemetriken wie Cyclomatic Complexity , Maintainability Index und Halstead Volume beeinträchtigen . Je mehr Funktionen Sie haben, desto schlimmer wird es.

Code Dokumentation wäre Ok - Tools wie mit phpDocumentor , aber unter Verwendung von Sami es kein Verfahren Dateien übertragen werden . Die Laravel-API-Dokumentation ist ein solcher Fall - es gibt keine Dokumentation zu Hilfsfunktionen : https://laravel.com/api/5.4

Codemetriken können mit Tools wie PhpMetrics analysiert werden . Wenn Sie PhpMetrics Version 1.x zur Analyse des Laravel 5.4-Framework-Codes verwenden, erhalten Sie sehr schlechte CC / MI / HV-Metriken für src / Illuminate / Foundation / helpers.php und src / Illuminate / Support / helpers.php Dateien .

Mehrere kontextbezogene Hilfsdateien (z. B. string_helpers.php , array_helpers.php usw.) würden diese fehlerhaften Metriken sicherlich verbessern, was zu einer einfacheren Verwaltung des Codes führen würde. Abhängig vom verwendeten Codedokumentationsgenerator wäre dies gut genug.

Es kann weiter verbessert werden, indem Hilfsklassen mit statischen Methoden verwendet werden, sodass sie mithilfe von Namespaces kontextualisiert werden können. Genau wie Laravel es schon mit Illuminate\Support\Strund Illuminate\Support\ArrKlassen macht. Dies verbessert sowohl die Codemetrik / Organisation als auch die Dokumentation. Klassen-Aliase könnten verwendet werden, um ihre Verwendung zu vereinfachen.

Die Strukturierung mit Klassen verbessert die Organisation und Dokumentation des Codes, aber andererseits verlieren wir diese großen kurzen und leicht zu merkenden globalen Funktionen. Wir können diesen Ansatz weiter verbessern, indem wir Funktionsaliasnamen für diese statischen Klassenmethoden erstellen. Dies kann entweder manuell oder dynamisch erfolgen.

Laravel verwendet intern den ersten Ansatz, indem Funktionen in den prozeduralen Hilfsdateien deklariert werden, die den statischen Klassenmethoden zugeordnet sind. Dies ist möglicherweise nicht die ideale Sache, da Sie alle Dinge (Dokumentblöcke / Argumente) neu deklarieren müssen.
Ich persönlich verwende einen dynamischen Ansatz mit einer HelperServiceProviderKlasse, die diese Funktionen in der Ausführungszeit erstellt:

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

Man kann sagen, dass dies über das Engineering hinausgeht, aber ich denke nicht. Es funktioniert ziemlich gut und kostet entgegen den Erwartungen keine relevante Ausführungszeit, zumindest bei Verwendung von PHP 7.x.

Paulo Freitas
quelle
8

Hier ist ein Bash-Shell-Skript, das ich erstellt habe, um Laravel 5-Fassaden sehr schnell zu erstellen.

Führen Sie dies in Ihrem Laravel 5-Installationsverzeichnis aus.

Nennen Sie es so:

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

Beispiel:

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

Wenn Sie dieses Beispiel ausführen, wird es die Verzeichnisse erstellen Facadesund Providersunter ‚your_laravel_installation_dir / app / MyApp‘.

Es werden die folgenden 3 Dateien erstellt und auf dem Bildschirm ausgegeben:

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

Danach wird eine Meldung angezeigt, die der folgenden ähnelt:

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

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

Aktualisieren Sie daher die Liste der Anbieter und Alias ​​in 'config / app.php'.

Lauf composer -o dumpautoload

Die "./app/MyApp/Facades/Helper.php" sieht ursprünglich so aus:

<?php

namespace App\MyApp\Facades;


class Helper
{
    //
}

Fügen Sie jetzt einfach Ihre Methoden in "./app/MyApp/Facades/Helper.php" hinzu.

So sieht "./app/MyApp/Facades/Helper.php" aus, nachdem ich eine Hilfsfunktion hinzugefügt habe.

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

Diese Funktion erwartet ein Muster und kann ein optionales zweites boolesches Argument akzeptieren.

Wenn die aktuelle URL mit dem an sie übergebenen Muster übereinstimmt, wird 'active' ausgegeben (oder 'class = "active"', wenn Sie dem Funktionsaufruf 'true' als zweites Argument hinzufügen).

Ich benutze es, um das aktive Menü hervorzuheben.

Unten ist der Quellcode für mein Skript. Ich hoffe, Sie finden es nützlich und lassen Sie mich wissen, wenn Sie Probleme damit haben.

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

Anstatt Ihre benutzerdefinierte Hilfsklasse einzuschließen, können Sie Ihre config/app.phpDatei auch unter Aliasnamen hinzufügen .

sollte so aussehen.

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

Fügen Sie dann Ihrem Helfer den Helper mit der Methode 'use Helper' hinzu, damit Sie einfach einen Teil der Methode in Ihrer Helper-Klasse aufrufen können.

eg. Helper::some_function();

In der Ressourcenansicht können Sie die Helper-Klasse bereits direkt aufrufen.

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

Dies ist jedoch immer noch der Ansatz des Entwicklercodierungsstils. Wir haben möglicherweise verschiedene Möglichkeiten, Probleme zu lösen, und ich möchte nur mitteilen, was ich auch für Anfänger habe.

Kenneth Sonntag
quelle
4

Benutzerdefiniertes Helferverzeichnis erstellen : Erstellen Sie zuerst das Helferverzeichnis im App-Verzeichnis. Erstellen einer hlper-Klassendefinition: Erstellen Sie jetzt eine einfache Hilfsfunktion , die zwei Zeichenfolgen verkettet. Erstellen Sie eine neue Datei MyFuncs.php in /app/Helpers/MyFuncs.php. Fügen Sie den folgenden Code hinzu

<?php

namespace App\Helpers;

class MyFuncs {

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

Namespace App \ Helpers; Definiert den Helpers-Namespace unter App-Namespace. Klasse MyFuncs {…} definiert die Hilfsklasse MyFuncs. öffentliche statische Funktion full_name ($ first_name, $ last_name) {…} definiert eine statische Funktion, die zwei Zeichenfolgenparameter akzeptiert und eine verkettete Zeichenfolge zurückgibt

Helfer Service bieten Klasse

Dienstanbieter werden zum automatischen Laden von Klassen verwendet. Wir müssen einen Dienstanbieter definieren, der alle unsere Hilfsklassen in das Verzeichnis / app / Helpers lädt.

Führen Sie den folgenden Handwerkerbefehl aus:

PHP Artisan machen: Anbieter HelperServiceProvider

Die Datei wird in erstellt /app/Providers/HelperServiceProvider.php

Open /app/Providers/HelperServiceProvider.php

Fügen Sie den folgenden Code hinzu:

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

HIER,

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.

Wir müssen jetzt den HelperServiceProvider registrieren und einen Alias ​​für unsere Helfer erstellen.

/config/app.phpDatei öffnen

Suchen Sie die Array-Variable des Anbieters

Fügen Sie die folgende Zeile hinzu

App\Providers\HelperServiceProvider::class,

Suchen Sie die Aliase-Array-Variable

Fügen Sie die folgende Zeile hinzu

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

Speichern Sie die Änderungen mit unserem benutzerdefinierten Helfer

Wir werden eine Route erstellen, die unsere benutzerdefinierte Hilfsfunktion Open /app/routes.php aufruft

Fügen Sie die folgende Routendefinition hinzu

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

HIER,

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

Erstellen Sie zuerst die Datei helpers.php im Verzeichnis App \ Http. Fügen Sie dann den folgenden Code in die Datei composer.json ein

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

Führen Sie als nächstes den folgenden Befehl aus

composer dump-autoload

Jetzt können Sie Ihre benutzerdefinierte Funktion in der Datei helpers.php definieren.

ujjal
quelle
3

Eine andere Möglichkeit, die ich verwendet habe, war: 1) eine Datei in app \ FolderName \ fileName.php erstellt und diesen Code darin enthalten, dh

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

2) Danach in unserer Klinge

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

das ist es. und es funktioniert

Dee
quelle
3

Best Practice zum Schreiben von benutzerdefinierten Helfern ist

1) appErstellen Sie im Verzeichnis des Projektstamms einen Ordner mit dem Namen Helpers (nur um den Code zu trennen und zu strukturieren).

2) Schreiben Sie in den Ordner psr-4-Dateien oder normale PHP-Dateien

Wenn die PHP-Dateien das Format psr-4 haben, werden sie automatisch geladen. Andernfalls fügen Sie die folgende Zeile in die Datei composer.json ein, die sich im Projektstammverzeichnis befindet

autoloadErstellen Sie innerhalb des Schlüssels einen neuen Schlüssel mit dem Namen fileszum Laden von Dateien zum Zeitpunkt des automatischen Ladens. Fügen Sie innerhalb des filesObjekts den Pfad ab dem App-Verzeichnis hinzu. Hier ein Beispiel.

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

PS: Versuchen Sie es, composer dump-autoloadwenn die Datei nicht geladen wurde.

Reiah Paul Sam
quelle
3

Erstellen Sie Helpers.php in app / Helper / Helpers.php

namespace App\Helper
class Helpers
{


}

Fügen Sie in Composer und Composer Update hinzu

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

Verwendung in Controller

Verwenden Sie App \ Helper \ Helpers

Verwenden Sie in der Ansicht Änderung in der Datei config-> app.php

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

Anruf in Sicht

<?php echo Helpers::function_name();  ?>
Abhishek Kumar
quelle
Vielen Dank, würde es Ihnen etwas ausmachen, Ihre Erklärung etwas zu erweitern?
Felipe Valdes
2
Wenn die Klasse einen Namespace hat, ist das Hinzufügen der Datei composer.jsonnutzlos, da das automatische Laden von psr-4 die Aufgabe übernimmt.
Arcesilas
2

in dir bootstrap \ autoload.php

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

Fügen Sie diese Datei hinzu

app\Helpers\function.php
panqingqiang
quelle
2

** **.

  • Status Helfer

** Neuen Helfer erstellen

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

Verwendung für den Controller und jede Ansichtsdatei

use App\Helpers\StatusHelper;

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

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

In Laravel 5.3 und höher hat das Laravel-Team alle prozeduralen Dateien ( routes.php) aus dem app/Verzeichnis verschoben , und der gesamte app/Ordner wird automatisch geladen psr-4. Die akzeptierte Antwort wird in diesem Fall funktionieren, aber es fühlt sich für mich nicht richtig an.

Also habe ich ein helpers/Verzeichnis im Stammverzeichnis meines Projekts erstellt und die Hilfedateien darin abgelegt, und in meiner composer.jsonDatei habe ich Folgendes getan:

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

Auf diese Weise meine app/ Verzeichnis immer noch ein automatisch geladenes psr-4-Verzeichnis, und die Helfer sind etwas besser organisiert.

Hoffe das hilft jemandem.

Mubashar Abbas
quelle
0

Hier gibt es einige gute Antworten, aber ich denke, das ist die einfachste. In Laravel 5.4 (und wahrscheinlich auch in früheren Versionen) können Sie eine Klasse an einem für Sie geeigneten Ort erstellen, z. B. App / Libraries / Helper.php

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

Dann können Sie es einfach in Ihrer Blade-Vorlage folgendermaßen aufrufen:

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

Wenn Sie @inject nicht verwenden möchten, machen Sie einfach die Funktion 'uppercasePara' als statisch und binden Sie den Aufruf wie folgt in Ihre Blade-Vorlage ein:

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

Keine Notwendigkeit für Aliase. Laravel löst die konkrete Klasse automatisch auf.

omarjebari
quelle