Heim >Backend-Entwicklung >PHP-Tutorial >Laravel-Kerninterpretation von Request

Laravel-Kerninterpretation von Request

不言
不言Original
2018-07-06 14:54:374120Durchsuche

Dieser Artikel stellt hauptsächlich die Kerninterpretation von Request in Laravel vor, die einen gewissen Referenzwert hat. Jetzt können Freunde in Not darauf verweisen.

Anfrage

Viele Frameworks Anforderungen des Clients werden zur einfachen Verwendung durch Anwendungen in Klassen abstrahiert, und Laravel bildet da keine Ausnahme. Die IlluminateHttpRequest-Klasse ist eine Abstraktion von Client-Anfragen im Laravel-Framework. Sie basiert auf der vom Symfony-Framework bereitgestellten Request-Komponente. Der heutige Artikel befasst sich kurz damit, wie Laravel ein Request-Objekt erstellt. Ich werde nicht zu viel über die Funktionen sagen, die das Request-Objekt für Anwendungen bereitstellt. Nachdem ich den Erstellungsprozess erläutert habe, wissen Sie, wo Sie zur Quelle gelangen müssen Suchen Sie nach den vom Request-Objekt bereitgestellten Methoden. Einige der von Request bereitgestellten Methoden sind jedoch nicht vollständig und einige davon werden nicht erläutert Die gewünschten Funktionen wurden während der Entwicklung erreicht. Sehen Sie sich den Quellcode von Request an, um zu sehen, ob es eine entsprechende Methode gibt. Die Ausführungsergebnisse jeder Methode sind in den Methodenkommentaren deutlich gekennzeichnet. Kommen wir zum Punkt.

Erstellen des Request-Objekts

Wir können in der index.php-Datei der Laravel-Anwendung sehen, dass das Request-Objekt erstellt wurde, bevor die Laravel-Anwendung offiziell gestartet wurde:

//public/index.php
$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    //创建request对象
    $request = Illuminate\Http\Request::capture()
);

Die HTTP-Anfrage des Clients ist ein Objekt der Klasse IlluminateHttpRequest

class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
    //新建Request实例
    public static function capture()
    {
        static::enableHttpMethodParameterOverride();

        return static::createFromBase(SymfonyRequest::createFromGlobals());
    }
}

Sie können dem Quellcode der Klasse IlluminateHttpRequest entnehmen, dass sie von der Klasse Symfony Request erbt, also in der implementiert ist IlluminateHttpRequest-Klasse Viele Funktionen werden basierend auf den von Symfony Reques bereitgestellten Funktionen implementiert. Aus dem obigen Code können Sie ersehen, dass die Methode capture beim Erstellen eines neuen Request-Objekts auch auf Instanzen der Klasse Symfony Request angewiesen ist.

namespace Symfony\Component\HttpFoundation;
class Request
{
    /**
     * 根据PHP提供的超级全局数组来创建Smyfony Request实例
     *
     * @return static
     */
    public static function createFromGlobals()
    {
        // With the php's bug #66606, the php's built-in web server
        // stores the Content-Type and Content-Length header values in
        // HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH fields.
        $server = $_SERVER;
        if ('cli-server' === PHP_SAPI) {
            if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) {
                $server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH'];
            }
            if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) {
                $server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE'];
            }
        }

        $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server);

        if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
            && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
        ) {
            parse_str($request->getContent(), $data);
            $request->request = new ParameterBag($data);
        }

        return $request;
    }
    
}

Es gibt einen Punkt im obigen Code, der einer zusätzlichen Erklärung bedarf. Ab PHP5.4 kann der integrierte Webserver von PHP über den Befehlszeileninterpreter gestartet werden, zum Beispiel:

php -S localhost:8000 -t htdocs

-S 9581b3ba3b9ee3c707d01b5722440004:298c9bd6ad6e8c821dc63aa0473d6209 Run with built-in web server.
-t ea23c61ebf6b70b26359136364366495     Specify document root ea23c61ebf6b70b26359136364366495 for built-in web server.

Es gibt jedoch einen Fehler im integrierten Webserver, der die beiden Anforderungsheader CONTENT_LENGTH und CONTENT_TYPE in HTTP_CONTENT_LENGTH und speichert HTTP_CONTENT_TYPE Um die Anforderungsheaderfelder im integrierten Server und im realen Server zu vereinheitlichen, wird hier eine spezielle Verarbeitung durchgeführt.

Symfony Request-Instanzen werden über superglobale Arrays in PHP erstellt. Diese superglobalen Arrays umfassen $_GET, $_POST, $_COOKIE, $_FILES und $_SERVER, die alle mit PHP zusammenhängenden superglobalen Arrays abdecken Bei der Erstellung einer Symfony-Request-Instanz werden die im Symfony-Paket bereitgestellten Instanzen auf der Grundlage dieser globalen Arrays erstellt Zugriffs- und Einstellungs-API der HTTP-Komponente. Leser, die sich für die von Symfony bereitgestellten ParamterBag-Beispiele interessieren, können den Quellcode selbst überprüfen. ServerBag

class Request
{

    /**
     * @param array                $query      The GET parameters
     * @param array                $request    The POST parameters
     * @param array                $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
     * @param array                $cookies    The COOKIE parameters
     * @param array                $files      The FILES parameters
     * @param array                $server     The SERVER parameters
     * @param string|resource|null $content    The raw body data
     */
    public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
    {
        $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
    }
    
    public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
    {
        $this->request = new ParameterBag($request);
        $this->query = new ParameterBag($query);
        $this->attributes = new ParameterBag($attributes);
        $this->cookies = new ParameterBag($cookies);
        $this->files = new FileBag($files);
        $this->server = new ServerBag($server);
        $this->headers = new HeaderBag($this->server->getHeaders());

        $this->content = $content;
        $this->languages = null;
        $this->charsets = null;
        $this->encodings = null;
        $this->acceptableContentTypes = null;
        $this->pathInfo = null;
        $this->requestUri = null;
        $this->baseUrl = null;
        $this->basePath = null;
        $this->method = null;
        $this->format = null;
    }
    
}
FileBagSie können sehen, dass die Symfony-Request-Klasse zusätzlich zu den oben genannten Attributen eine vollständige Abstraktion von HTTP-Anfragen bildet. Wir können leicht über Instanzattribute darauf zugreifenHeaderBag, ParamterBag und andere Attribute dieser HTTP-Anfragen.

Nachdem Laravel die Symfony Request-Instanz erhalten hat, klont Laravel die Instanz und setzt einige ihrer Eigenschaften zurück: Method

namespace Illuminate\Http;
class Request extends ....
{
    //在Symfony request instance的基础上创建Request实例
    public static function createFromBase(SymfonyRequest $request)
    {
        if ($request instanceof static) {
            return $request;
        }

        $content = $request->content;

        $request = (new static)->duplicate(
            $request->query->all(), $request->request->all(), $request->attributes->all(),
            $request->cookies->all(), $request->files->all(), $request->server->all()
        );

        $request->content = $content;

        $request->request = $request->getInputSource();

        return $request;
    }
    
    public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
    {
        return parent::duplicate($query, $request, $attributes, $cookies, $this->filterFiles($files), $server);
    }
}
    //Symfony Request中的 duplicate方法
    public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
    {
        $dup = clone $this;
        if (null !== $query) {
            $dup->query = new ParameterBag($query);
        }
        if (null !== $request) {
            $dup->request = new ParameterBag($request);
        }
        if (null !== $attributes) {
            $dup->attributes = new ParameterBag($attributes);
        }
        if (null !== $cookies) {
            $dup->cookies = new ParameterBag($cookies);
        }
        if (null !== $files) {
            $dup->files = new FileBag($files);
        }
        if (null !== $server) {
            $dup->server = new ServerBag($server);
            $dup->headers = new HeaderBag($dup->server->getHeaders());
        }
        $dup->languages = null;
        $dup->charsets = null;
        $dup->encodings = null;
        $dup->acceptableContentTypes = null;
        $dup->pathInfo = null;
        $dup->requestUri = null;
        $dup->baseUrl = null;
        $dup->basePath = null;
        $dup->method = null;
        $dup->format = null;

        if (!$dup->get('_format') && $this->get('_format')) {
            $dup->attributes->set('_format', $this->get('_format'));
        }

        if (!$dup->getRequestFormat(null)) {
            $dup->setRequestFormat($this->getRequestFormat(null));
        }

        return $dup;
    }
CharsetNachdem das Request-Objekt erstellt wurde, können wir die von ihm bereitgestellten Funktionen problemlos in Laravel anwenden Wenn Sie bei Verwendung des Request-Objekts nicht wissen, ob es die gewünschte Funktion implementiert, können Sie einfach direkt zur Quellcodedatei von

gehen, um sie zu überprüfen. Zum Beispiel:

/**
 * Get the full URL for the request.
 * 获取请求的URL(包含host, 不包括query string)
 *
 * @return string
 */
public function fullUrl()
{
    $query = $this->getQueryString();

    $question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';

    return $query ? $this->url().$question.$query : $this->url();
}

/**
 * Get the full URL for the request with the added query string parameters.
 * 获取包括了query string 的完整URL
 *
 * @param  array  $query
 * @return string
 */
public function fullUrlWithQuery(array $query)
{
    $question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';

    return count($this->query()) > 0
        ? $this->url().$question.http_build_query(array_merge($this->query(), $query))
        : $this->fullUrl().$question.http_build_query($query);
}

Die Station, die die Anforderung durchläuft

IlluminateHttpRequestNach dem Erstellen des Anforderungsobjekts wird der HTTP-Kernel von Laravel weiterhin ausgeführt: Laden Sie den Dienstanbieter, um die Laravel-Anwendung zu steuern, und starten Sie die Anwendung , und lassen Sie die Anforderung die Basis passieren. Die Middleware sucht über den Router nach der Route, die der Anforderung entspricht, führt die übereinstimmende Route aus und die Anforderung erreicht die Controller-Methode über die Route zur Middleware.

Zusammenfassung

Wenn die Anfrage schließlich die entsprechende Controller-Methode erreicht, ist ihre Mission im Grunde abgeschlossen. Bei der Controller-Methode werden die Eingabeparameter aus der Anfrage abgerufen und dann werden bestimmte Aspekte der Anwendung ausgeführt Sobald die Geschäftslogik das Ergebnis erhält, wird das Ergebnis in ein Antwortobjekt umgewandelt und an den Client zurückgegeben, der die Anfrage initiiert hat.

Dieser Artikel befasst sich hauptsächlich mit dem Request-Objekt in Laravel. Er möchte vor allem wissen, wie wir herausfinden können, welche Funktionen Request in Laravel uns derzeit zur Verfügung stellt, um zu vermeiden, dass wir das Rad im Geschäftscode neu erfinden müssen, um Request zu implementieren . Bereits bereitgestellte Methoden.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

Laravel Core Interpretation Facades

Das obige ist der detaillierte Inhalt vonLaravel-Kerninterpretation von Request. 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