Heim  >  Artikel  >  Backend-Entwicklung  >  Laravel-Kerninterpretation von Response

Laravel-Kerninterpretation von Response

不言
不言Original
2018-07-06 14:56:583033Durchsuche

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

Wir haben In den beiden vorherigen Abschnitten haben wir über den Controller bzw. das Request-Objekt von Laravel gesprochen. Im Abschnitt über das Request-Objekt haben wir untersucht, wie das Request-Objekt erstellt wird und wo die von ihm unterstützten Methoden definiert sind Im Detail wird beschrieben, wie die Controller-Methode gefunden wird, die der Anforderung entspricht, und dann der Handler ausgeführt wird. In diesem Abschnitt werden wir über den verbleibenden Teil sprechen, wie das Ausführungsergebnis der Controller-Methode in das Antwortobjekt umgewandelt und dann an das zurückgegeben wird Kunde.

Antwort erstellen

Gehen wir zurück zum Codeblock, in dem Laravel den Routenhandler ausführt und die Antwort zurückgibt:

namespace Illuminate\Routing;
class Router implements RegistrarContract, BindingRegistrar
{     
    protected function runRoute(Request $request, Route $route)
    {
        $request->setRouteResolver(function () use ($route) {
            return $route;
        });

        $this->events->dispatch(new Events\RouteMatched($route, $request));

        return $this->prepareResponse($request,
            $this->runRouteWithinStack($route, $request)
        );
    }
    
    protected function runRouteWithinStack(Route $route, Request $request)
    {
        $shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
                            $this->container->make('middleware.disable') === true;
        //收集路由和控制器里应用的中间件
        $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route);

        return (new Pipeline($this->container))
                    ->send($request)
                    ->through($middleware)
                    ->then(function ($request) use ($route) {
                        return $this->prepareResponse(
                            $request, $route->run()
                        );
                    });
    
    }
}

Wir haben es bereits im Abschnitt über Controller erwähnt Die

-Methode ist der Ort, an dem der Routing-Handler (Controller-Methode oder Abschluss-Handler) schließlich ausgeführt wird. Durch den obigen Code können wir auch sehen, dass das Ausführungsergebnis an die

-Methode übergeben wird Nachdem der Stream zu runRouteWithinStack zurückgekehrt ist, wird die Methode Router erneut ausgeführt, um das an den Client zurückzugebende Antwortobjekt zu erhalten. Schauen wir uns die Methode prepareResponse genauer an. runRoute

class Router implements RegistrarContract, BindingRegistrar
{
    /**
     * 通过给定值创建Response对象
     *
     * @param  \Symfony\Component\HttpFoundation\Request  $request
     * @param  mixed  $response
     * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
     */
    public function prepareResponse($request, $response)
    {
        return static::toResponse($request, $response);
    }
    
    public static function toResponse($request, $response)
    {
        if ($response instanceof Responsable) {
            $response = $response->toResponse($request);
        }

        if ($response instanceof PsrResponseInterface) {
            $response = (new HttpFoundationFactory)->createResponse($response);
        } elseif (! $response instanceof SymfonyResponse &&
                   ($response instanceof Arrayable ||
                    $response instanceof Jsonable ||
                    $response instanceof ArrayObject ||
                    $response instanceof JsonSerializable ||
                    is_array($response))) {
            $response = new JsonResponse($response);
        } elseif (! $response instanceof SymfonyResponse) {
            $response = new Response($response);
        }

        if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) {
            $response->setNotModified();
        }

        return $response->prepare($request);
    }
}
prepareResponseIm obigen Code sehen wir, dass es drei Arten von Antworten gibt:prepareResponse

Aus der Logik in

können Sie ersehen, dass das Routing egal welchen Wert zurückgibt Das Ausführungsergebnis wird schließlich von Laravel in ein Antwortobjekt konvertiert, und diese Objekte sind Objekte der SymfonyComponentHttpFoundationResponse-Klasse oder ihrer Unterklassen. Von hier aus können wir sehen, dass Laravel's Response ebenso wie Request auf der
Class Name Representation
PsrResponseInterface(PsrHttpMessageResponseInterface的别名) Psr规范中对服务端响应的定义
IlluminateHttpJsonResponse (SymfonyComponentHttpFoundationResponse的子类) Laravel中对服务端JSON响应的定义
IlluminateHttpResponse (SymfonyComponentHttpFoundationResponse的子类) Laravel中对普通的非JSON响应的定义
-Komponente des Symfony-Frameworks basiert.

prepareResponseWerfen wir einen Blick auf die Konstruktionsmethode von SymfonyComponentHttpFoundationResponse: HttpFoundation

namespace Symfony\Component\HttpFoundation;
class Response
{
    public function __construct($content = '', $status = 200, $headers = array())
    {
        $this->headers = new ResponseHeaderBag($headers);
        $this->setContent($content);
        $this->setStatusCode($status);
        $this->setProtocolVersion('1.0');
    }
    //设置响应的Content
    public function setContent($content)
    {
        if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
            throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content)));
        }

        $this->content = (string) $content;

        return $this;
    }
}

Der Rückgabewert des Routenhandlers wird also beim Erstellen des Response-Objekts auf das Inhaltsattribut des Objekts gesetzt, und das Der Wert dieses Attributs wird an den Antwortinhalt der Antwort des Clients zurückgegeben.

Antwortheader festlegen

Nachdem Sie das Antwortobjekt generiert haben, müssen Sie die

-Methode des Objekts ausführen. Diese Methode ist in der Klasse

definiert. Passen Sie die Antwort so an, dass sie dem HTTP/1.1-Protokoll (RFC 2616) entspricht.

namespace Symfony\Component\HttpFoundation;
class Response
{
    //在响应被发送给客户端之前对其进行修订使其能遵从HTTP/1.1协议
    public function prepare(Request $request)
    {
        $headers = $this->headers;

        if ($this->isInformational() || $this->isEmpty()) {
            $this->setContent(null);
            $headers->remove('Content-Type');
            $headers->remove('Content-Length');
        } else {
            // Content-type based on the Request
            if (!$headers->has('Content-Type')) {
                $format = $request->getRequestFormat();
                if (null !== $format && $mimeType = $request->getMimeType($format)) {
                    $headers->set('Content-Type', $mimeType);
                }
            }

            // Fix Content-Type
            $charset = $this->charset ?: 'UTF-8';
            if (!$headers->has('Content-Type')) {
                $headers->set('Content-Type', 'text/html; charset='.$charset);
            } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {
                // add the charset
                $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);
            }

            // Fix Content-Length
            if ($headers->has('Transfer-Encoding')) {
                $headers->remove('Content-Length');
            }

            if ($request->isMethod('HEAD')) {
                // cf. RFC2616 14.13
                $length = $headers->get('Content-Length');
                $this->setContent(null);
                if ($length) {
                    $headers->set('Content-Length', $length);
                }
            }
        }

        // Fix protocol
        if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
            $this->setProtocolVersion('1.1');
        }

        // Check if we need to send extra expire info headers
        if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) {
            $this->headers->set('pragma', 'no-cache');
            $this->headers->set('expires', -1);
        }

        $this->ensureIEOverSSLCompatibility($request);

        return $this;
    }
}
prepareSymfonyComponentHttpFoundationResposne hat entsprechende

-Sets für verschiedene Situationen, wie z. B.

, prepare usw. Dies sind unsere allgemeinen Headerfelder. response headerContent-TypeAntwort sendenContent-Length

Nachdem die Antwort erstellt und eingerichtet wurde, durchläuft sie die Nachoperationen des Routings und der Framework-Middleware. In den Nachoperationen der Middleware befindet sich die Antwort im Allgemeinen weiter verarbeitet, und schließlich fließt das Programm zurück zum HTTP-Kernel, und der HTTP-Kernel sendet die Antwort an den Client. Schauen wir uns diesen Teil des Codes an. Die Logik von

//入口文件public/index.php
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);
rrree

ist sehr einfach zu verstehen. Setzen Sie die zuvor festgelegten Header in das Header-Feld der HTTP-Antwort. Der Inhalt wird wiedergegeben und in die Hauptentität der HTTP-Antwort eingefügt. Schließlich sendet PHP die vollständige HTTP-Antwort an den Client.

Nach dem Senden der Antwort führt der HTTP-Kernel die Methode send aus, um die Methode

in der Terminate-Middleware aufzurufen, und führt schließlich die Methode

der Anwendung aus, um den gesamten Anwendungslebenszyklus zu beenden (von vom Empfang der Anfrage bis zur Rücksendung der Antwort (Fertig stellen). terminateterminateDas Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website. termiate

Verwandte Empfehlungen:

Laravel Core Interpretation Request


Laravel Core Interpretation Facades

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