Kurze Analyse des laufenden Pimple-Prozesses (PHP-Container)

藏色散人
Freigeben: 2023-04-08 09:42:01
nach vorne
2658 Leute haben es durchsucht

Kurze Analyse des laufenden Pimple-Prozesses (PHP-Container)

Erforderliche Wissenspunkte

Abschluss

Abschlusspakete und anonym Funktionen wurden in PHP5.3.0 eingeführt.

Abschluss bezieht sich auf:

Eine Funktion, die beim Erstellen den umgebenden Zustand kapselt. Auch wenn die Umgebung, in der sich der Verschluss befindet, nicht mehr existiert, ist der im Verschluss eingekapselte Zustand weiterhin vorhanden.

Theoretisch sind Schließungen und anonyme Funktionen unterschiedliche Konzepte. Aber PHP behandelt es als dasselbe Konzept.

Tatsächlich sind Abschlüsse und anonyme Funktionen als Funktionen getarnte Objekte. Sie sind Instanzen der Klasse Closure.

Abschlüsse sind wie Strings und Ganzzahlen erstklassige Werttypen.

Abschluss erstellen:

<?php
$closure = function ($name) {
    return &#39;Hello &#39; . $name;
};
echo $closure(&#39;nesfo&#39;);//Hello nesfo
var_dump(method_exists($closure, &#39;__invoke&#39;));//true
Nach dem Login kopieren

Der Grund, warum wir die Variable $closure aufrufen können, liegt darin, dass der Wert dieser Variablen ein Abschluss ist und das Abschlussobjekt < implementiert 🎜>Magische Methode. Solange nach dem Variablennamen () steht, findet PHP die Methode __invoke() und ruft sie auf. __invoke()

Normalerweise werden PHP-Abschlüsse als Rückrufe von Funktionen verwendet.

, array_map() Methoden verwenden alle Callback-Funktionen. Dies ist der beste Zeitpunkt, um Abschlüsse zu verwenden! preg_replace_callback()

Zum Beispiel:

<?php
$numbersPlusOne = array_map(function ($number) {
    return $number + 1;
}, [1, 2, 3]);
print_r($numbersPlusOne);
Nach dem Login kopieren

erhält das Ergebnis:

[2, 3, 4]
Nach dem Login kopieren

Vor Schließungen konnten Sie benannte Funktionen nur einzeln erstellen und diese Funktion dann namentlich referenzieren. Dadurch wird die Codeausführung etwas langsamer und die Implementierung des Rückrufs wird vom Nutzungsszenario isoliert.

<?php
function incrementNum ($number) {
    return $number + 1;
}
$numbersPlusOne = array_map(&#39;incrementNum&#39;, [1, 2, 3]);
print_r($numbersPlusOne);
Nach dem Login kopieren

SPL

ArrayAccess

implementiert die

-Schnittstelle, die es Objekten ermöglicht, wie Arrays zu funktionieren. Die ArrayAccess-Schnittstelle enthält vier Methoden, die implementiert werden müssen: ArrayAccess

interface ArrayAccess {
    //检查一个偏移位置是否存在 
    public mixed offsetExists ( mixed $offset  );
    
    //获取一个偏移位置的值 
    public mixed offsetGet( mixed $offset  );
    
    //设置一个偏移位置的值 
    public mixed offsetSet ( mixed $offset  );
    
    //复位一个偏移位置的值 
    public mixed offsetUnset  ( mixed $offset  );
}
Nach dem Login kopieren

SplObjectStorage

Die Klasse implementiert eine Map mit Objekten als Schlüssel oder eine Sammlung von Objekten ( If Sie ignorieren die dem Objekt entsprechenden Daten als Schlüssel) dieser Datenstruktur. Eine Instanz dieser Klasse ähnelt einem Array, die darin gespeicherten Objekte sind jedoch alle eindeutig. Ein weiteres Merkmal dieser Klasse besteht darin, dass Sie das angegebene Objekt direkt daraus löschen können, ohne die gesamte Sammlung durchlaufen oder durchsuchen zu müssen. SplObjectStorage

Syntax ::class

Weil

eine Zeichenfolge darstellt. Der Vorteil der Verwendung von ::class besteht darin, dass Sie es in der IDE direkt in ::class umbenennen können und die IDE dann automatisch die relevanten Referenzen verarbeitet. class

Gleichzeitig wird PHP, wenn es den entsprechenden Code ausführt, nicht zuerst die entsprechende Klasse laden.

Ähnlich kann auch die automatisierte Code-Inspektion

Klassen korrekt identifizieren. inspect

Eine kurze Analyse des Pimple-Container-Prozesses

Pimpl ist ein beliebter Container in der PHP-Community. Es gibt nicht viel Code, siehe

https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php für Details.

Unsere Anwendung kann basierend auf Pimple entwickelt werden:

namespace EasyWeChat\Foundation;
use Pimple\Container;
class Application extends Container
{
    /**
     * Service Providers.
     *
     * @var array
     */
    protected $providers = [
        ServiceProviders\ServerServiceProvider::class,
        ServiceProviders\UserServiceProvider::class
    ];
    /**
     * Application constructor.
     *
     * @param array $config
     */
    public function __construct($config)
    {
        parent::__construct();
        $this[&#39;config&#39;] = function () use ($config) {
            return new Config($config);
        };
        if ($this[&#39;config&#39;][&#39;debug&#39;]) {
            error_reporting(E_ALL);
        }
        $this->registerProviders();
    }
    /**
     * Add a provider.
     *
     * @param string $provider
     *
     * @return Application
     */
    public function addProvider($provider)
    {
        array_push($this->providers, $provider);
        return $this;
    }
    /**
     * Set providers.
     *
     * @param array $providers
     */
    public function setProviders(array $providers)
    {
        $this->providers = [];
        foreach ($providers as $provider) {
            $this->addProvider($provider);
        }
    }
    /**
     * Return all providers.
     *
     * @return array
     */
    public function getProviders()
    {
        return $this->providers;
    }
    /**
     * Magic get access.
     *
     * @param string $id
     *
     * @return mixed
     */
    public function __get($id)
    {
        return $this->offsetGet($id);
    }
    /**
     * Magic set access.
     *
     * @param string $id
     * @param mixed  $value
     */
    public function __set($id, $value)
    {
        $this->offsetSet($id, $value);
    }
}
Nach dem Login kopieren

So verwenden Sie unsere Anwendung:

$app = new Application([]);
$user = $app->user;
Nach dem Login kopieren

Danach können wir die Methode des $user-Objekts verwenden . Wir haben festgestellt, dass es kein Attribut $this->user gibt, es aber direkt verwendet werden kann. Hauptsächlich die Rolle dieser beiden Methoden:

public function offsetSet($id, $value){}
public function offsetGet($id){}
Nach dem Login kopieren

Im Folgenden erklären wir, was Pimple tut, wenn es diese beiden Codezeilen ausführt. Aber bevor wir dies erklären, werfen wir einen Blick auf einige Kernkonzepte von Containern.

Dienstanbieter

Dienstanbieter ist die Brücke zwischen dem Container und der spezifischen Funktionsimplementierungsklasse. Dienstanbieter müssen die Schnittstelle implementieren

:ServiceProviderInterface

namespace Pimple;
/**
 * Pimple service provider interface.
 *
 * @author  Fabien Potencier
 * @author  Dominik Zogg
 */
interface ServiceProviderInterface
{
    /**
     * Registers services on the given container.
     *
     * This method should only be used to configure services and parameters.
     * It should not get services.
     *
     * @param Container $pimple A container instance
     */
    public function register(Container $pimple);
}
Nach dem Login kopieren

Alle Dienstanbieter müssen die Schnittstellenregistermethode implementieren.

In unserer Anwendung gibt es standardmäßig zwei Dienstanbieter:

protected $providers = [
    ServiceProviders\ServerServiceProvider::class,
    ServiceProviders\UserServiceProvider::class
];
Nach dem Login kopieren

Am Beispiel von

schauen wir uns die Code-Implementierung an: UserServiceProvider

namespace EasyWeChat\Foundation\ServiceProviders;
use EasyWeChat\User\User;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
 * Class UserServiceProvider.
 */
class UserServiceProvider implements ServiceProviderInterface
{
    /**
     * Registers services on the given container.
     *
     * This method should only be used to configure services and parameters.
     * It should not get services.
     *
     * @param Container $pimple A container instance
     */
    public function register(Container $pimple)
    {
        $pimple[&#39;user&#39;] = function ($pimple) {
            return new User($pimple[&#39;access_token&#39;]);
        };
    }
}
Nach dem Login kopieren

Wir sehen, dass The Die Registrierungsmethode des Dienstanbieters fügt dem Container Attribute

hinzu, aber was zurückgegeben wird, ist kein Objekt, sondern ein Abschluss. Ich werde das später erklären. user

Dienstregistrierung

Wir verwenden

im Konstruktor in Application, um alle Dienstanbieter zu registrieren: $this->registerProviders();

private function registerProviders()
{
    foreach ($this->providers as $provider) {
        $this->register(new $provider());
    }
}
Nach dem Login kopieren

Sorgfältig hinschauen, finden wir dass der Dienstanbieter hier instanziiert wird und die Registermethode des Containers Pimple heißt:

public function register(ServiceProviderInterface $provider, array $values = array())
{
    $provider->register($this);
    foreach ($values as $key => $value) {
        $this[$key] = $value;
    }
    return $this;
}
Nach dem Login kopieren

Und die

-Methode des Dienstanbieters wird hier aufgerufen, was wir im vorherigen Abschnitt erwähnt haben. Angekommen: Die Registrierungsmethode fügt dem Container Attribute register hinzu, gibt jedoch kein Objekt, sondern einen Abschluss zurück. user

Wenn wir das Attribut Benutzer zum Container Pimple hinzufügen, wird die Methode

aufgerufen: Weisen Sie den Attributen offsetSet($id, $value) und Schlüsseln des Containers Pimple jeweils Werte zu: values

$this->values[$id] = $value;
$this->keys[$id] = true;
Nach dem Login kopieren

Hier haben wir die Klasse

, die tatsächlich die eigentliche Funktionalität bereitstellt, noch nicht instanziiert. Die Registrierung des Dienstleisters ist jedoch abgeschlossen. EasyWeChatUserUsr

Wenn wir hier ausführen:

$user = $app->user;
Nach dem Login kopieren

ruft offsetGet($id) auf und instanziiert die echte Klasse:

$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;
$this->frozen[$id] = true;
return $val;
Nach dem Login kopieren

$raw erhält den Abschluss:

$pimple[&#39;user&#39;] = function ($pimple) {
    return new User($pimple[&#39;access_token&#39;]);
};
Nach dem Login kopieren

$raw($this)返回的是实例化的对象User。也就是说只有实际调用才会去实例化具体的类。后面我们就可以通过$this['user']或者$this->user调用User类里的方法了。

当然,Pimple里还有很多特性值得我们去深入研究,这里不做过多讲解。

更多相关php知识,请访问php教程

Das obige ist der detaillierte Inhalt vonKurze Analyse des laufenden Pimple-Prozesses (PHP-Container). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:cnblogs.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!