Heim >Backend-Entwicklung >PHP-Tutorial >So verwenden Sie makrofähige Makros in Laravel

So verwenden Sie makrofähige Makros in Laravel

不言
不言Original
2018-07-10 14:10:483022Durchsuche

Dieser Artikel stellt hauptsächlich die Verwendung von Macroable-Makros in Laravel vor. Jetzt kann ich ihn mit Ihnen teilen.

Definition der Baidu-Enzyklopädie Informatik ist ein Begriff für Stapelverarbeitung. Im Allgemeinen handelt es sich bei einem Makro um eine Regel oder ein Muster bzw. eine Syntaxersetzung, die verwendet wird, um zu erklären, wie eine bestimmte Eingabe (normalerweise eine Zeichenfolge) gemäß vordefinierten Regeln in eine entsprechende Ausgabe (normalerweise eine Zeichenfolge) umgewandelt wird. Diese Ersetzung erfolgt zur Zeit vor der Kompilierung und wird als Makroerweiterung bezeichnet.
  • Ich kam zum ersten Mal mit Makros in Kontakt, als ich an der Uni einen Computer-Grundkurs belegte und der Lehrer mir von

    Büro erzählte. Damals schenkte der Lehrer der Einführung der Makrooperation nicht viel Aufmerksamkeit. Er erinnerte sich nur daran, dass diese Operation sehr leistungsfähig war und die tägliche Arbeit erleichtern konnte.

  • Heute sprechen wir über Makrooperationen in

    Laravel


Zunächst einmal der komplette Quellcode

<?php

namespace Illuminate\Support\Traits;

use Closure;
use ReflectionClass;
use ReflectionMethod;
use BadMethodCallException;

trait Macroable
{
    /**
     * The registered string macros.
     *
     * @var array
     */
    protected static $macros = [];

    /**
     * Register a custom macro.
     *
     * @param  string $name
     * @param  object|callable  $macro
     *
     * @return void
     */
    public static function macro($name, $macro)
    {
        static::$macros[$name] = $macro;
    }

    /**
     * Mix another object into the class.
     *
     * @param  object  $mixin
     * @return void
     */
    public static function mixin($mixin)
    {
        $methods = (new ReflectionClass($mixin))->getMethods(
            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
        );

        foreach ($methods as $method) {
            $method->setAccessible(true);

            static::macro($method->name, $method->invoke($mixin));
        }
    }

    /**
     * Checks if macro is registered.
     *
     * @param  string  $name
     * @return bool
     */
    public static function hasMacro($name)
    {
        return isset(static::$macros[$name]);
    }

    /**
     * Dynamically handle calls to the class.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public static function __callStatic($method, $parameters)
    {
        if (! static::hasMacro($method)) {
            throw new BadMethodCallException("Method {$method} does not exist.");
        }

        if (static::$macros[$method] instanceof Closure) {
            return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters);
        }

        return call_user_func_array(static::$macros[$method], $parameters);
    }

    /**
     * Dynamically handle calls to the class.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (! static::hasMacro($method)) {
            throw new BadMethodCallException("Method {$method} does not exist.");
        }

        $macro = static::$macros[$method];

        if ($macro instanceof Closure) {
            return call_user_func_array($macro->bindTo($this, static::class), $parameters);
        }

        return call_user_func_array($macro, $parameters);
    }
}

  • MethodeMacroable::macro

public static function macro($name, $macro)
{
    static::$macros[$name] = $macro;
}
Ein sehr einfacher Code,

kann einen Abschluss oder übergeben Objekt. Der Grund, warum es möglich ist, Objekte zu übergeben, dank der magischen Methode $macro

in
    PHP
  • Macroable::mixin

  • Diese Methode besteht darin, a zu übergeben. Das Rückgabeergebnis der Methode des Objekts wird in das ursprüngliche Objekt eingefügt.
class Father
{
    // 通过增加魔术方法**__invoke**我们就可以把对象当做闭包来使用了。
    public function __invoke()
    {
        echo __CLASS__;
    }
}

class Child
{
    use \Illuminate\Support\Traits\Macroable;
}

// 增加了宏指令之后,我们就能调用 Child 对象中不存在的方法了
Child::macro('show', new Father);
// 输出:Father
(new Child)->show();

Wie Sie dem obigen Code entnehmen können, kann

eine Klassenmethode an eine Makroklasse binden . Es ist zu beachten, dass die Methode einen Abschlusstyp zurückgeben muss.

mixin

  • Methode

    Macroable::hasMacro

    public static function mixin($mixin)
    {
        // 通过反射获取该对象中所有公开和受保护的方法
        $methods = (new ReflectionClass($mixin))->getMethods(
            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
        );
    
        foreach ($methods as $method) {
            // 设置方法可访问,因为受保护的不能在外部调用
            $method->setAccessible(true);
            
            // 调用 macro 方法批量创建宏指令
            static::macro($method->name, $method->invoke($mixin));
        }
    }
    
    // 实际使用
    class Father
    {
        public function say()
        {
            return function () {
                echo 'say';
            };
        }
    
        public function show()
        {
            return function () {
                echo 'show';
            };
        }
    
        protected function eat()
        {
            return function () {
                echo 'eat';
            };
        }
    }
    
    class Child
    {
        use \Illuminate\Support\Traits\Macroable;
    }
    
    // 批量绑定宏指令
    Child::mixin(new Father);
    
    $child = new Child;
    // 输出:say
    $child->say();
    // 输出:show
    $child->show();
    // 输出:eat
    $child->eat();
  • Diese Methode ist relativ einfach und überhaupt nicht kompliziert. Sie ermittelt lediglich, ob eine Makroanweisung vorhanden ist. Normalerweise empfiehlt es sich, dies zu überprüfen, bevor Sie Makros verwenden.

  • und

    Methoden Macroable::__callMacroable::__callStatic

  • Aufgrund dieser beiden Methoden können wir zusätzlich zu The Makrooperationen durchführen Die Ausführungsmethoden sind unterschiedlich, aber die Codes sind größtenteils gleich. Lassen Sie uns über

public static function hasMacro($name)
{
    return isset(static::$macros[$name]);
}
__call in der obigen Operation sprechen. Wenn wir das Makro binden, können wir die Attribute von bis

im Abschluss aufrufen, da wir in der $this-Methode das verwenden Child Methode. __callClosure::bindToErklärung von

von der offiziellen Website: Kopieren Sie das aktuelle Abschlussobjekt und binden Sie das angegebene $this-Objekt und den angegebenen Klassenbereich.
Closure::bindToMakros zu Klassen in Laravel hinzufügen

Viele Klassen in Laravel

verwenden Makros trait


Zum Beispiel
möchten wir dieser Klasse eine Methode hinzufügen, werden aber den darin enthaltenen Code nicht berühren.
IlluminateFilesystemFilesystem::class

    Wir müssen nur Makros zur
  1. -Methode hinzufügen (Sie können auch einen neuen Dienstanbieter erstellen, um speziell damit umzugehen)

    AppProvidersAppServiceProvider::register


  2. 1. Fügen Sie dann eine Testroute hinzu, um unsere neu hinzugefügte Methode zu testen


2. Öffnen Sie dann den Browser und führen Sie ihn aus. Sie werden feststellen, dass unser Code normal ausgeführt und die Ergebnisse ausgegeben werden kann

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird hilfreich sein. Für weitere verwandte Inhalte achten Sie bitte auf die chinesische PHP-Website!

Verwandte Empfehlungen:

Analyse von Laravel’s Eloquent ORM


Analyse von Laravel’s grundlegenden Migrationen

Das obige ist der detaillierte Inhalt vonSo verwenden Sie makrofähige Makros in Laravel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn