Laravel Core Interpretation response

Source: Internet
Author: User
This article mainly introduces about the Laravel core interpretation of response, has a certain reference value, now share to everyone, the need for friends can refer to

Response

In the first two sections we talked about the Laravel controller and the request object, and in the section of the request object we looked at how the request object was created and where the method it supported was defined. When we talk about the controller, we describe in detail how to find the Controller method for the request and then execute the handler, and in this section we will say how the execution result of the Controller method is converted to the Response object response and then returned to the client.

Create response

Let's go back to the code block where the Laravel execution route handler returns the response:

Namespace Illuminate\routing;class Router implements Registrarcontract, bindingregistrar{protected function Runro  Ute (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 (' Middlewa        Re.disable ') = = = true; Collects middleware $middleware for routing and controller applications = $shouldSkipMiddleware?        []: $this->gatherroutemiddleware ($route); Return (new Pipeline ($this->container))->send ($request)->through ($middlew                 IS)   ->then (function ($request) use ($route) {return $this->prepareresponse (                    $request, $route->run ());        }); }}

In the section on the controller, we have already mentioned that the Runroutewithinstack method is where the final execution of the route handler (Controller method or closure handler) is, and we can see from the above code that the result of the execution is passed to the Prepareresponse method for Router , and once the program flow returns to Runroute , it executes once prepareresponse The method gets the response object to return to the client, so let's look at the prepareresponse method in more detail.

Class Router implements Registrarcontract, bindingregistrar{/** * Create response objects with given values * * @param \symfony\c Omponent\httpfoundation\request $request * @param mixed $response * @return \illuminate\http\response|\illumina Te\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)->createres        Ponse ($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); }}

In the above code we see three kinds of response:

Class Name Representation
Psrresponseinterface (alias of Psrhttpmessageresponseinterface) Definition of service-side response in the PSR specification
Illuminatehttpjsonresponse (sub-class of Symfonycomponenthttpfoundationresponse) Definition of the server-side JSON response in Laravel
Illuminatehttpresponse (sub-class of Symfonycomponenthttpfoundationresponse) Definition of generic non-JSON response in Laravel

prepareResponsethe logic in this can be seen, regardless of what value is returned by the route execution result, which is eventually converted to a response object by Laravel. These objects are objects of the Symfonycomponenthttpfoundationresponse class or its subclasses. From here it can be seen that the same laravel as the request response is also dependent on the components of the Symfony framework HttpFoundation .

Let's take a look at how the Symfonycomponenthttpfoundationresponse is constructed:

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 ');    }    Sets the content public function for the response    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;    }}

So the return value of the route handler is set to the object's content property in the Startup response object, and the value of the property is the response to the response returned to the client.

Set Response headers

The prepare method of the object is executed after the response object is generated, and the method is defined in the Symfony\component\httpfoundation\resposne class. Its main purpose is to fine-tune the response to comply with the http/1.1 protocol (RFC 2616).

namespace Symfony\component\httpfoundation;class response{//Revise the response before it is sent to the client so that it complies with the HTTP/1.1 protocol public Function PREPA        Re (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 (' Cont                Ent-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-t Ype '). ';            Charset= '. $charset); }//Fix content-length if ($headers->has (' transfer-encoding ')) {$headers->rem            Ove (' Content-length '); } if ($request->ismethod (' HEAD ')) {//cf. RFC2616 14.13 $length = $headers-&G                T;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; }}

prepareFor various situations response header , such as Content-Type , and Content-Length so on, these are our common header fields.

Send response

After the response is created and set up, it flows through the post operation of the Routing and Framework middleware, and in the post-operation of the middleware, the response is usually further processed, and finally the program flows back to the HTTP kernel where the HTTP kernel sends the response to the client , let's take a look at this part of the code.

Entry file 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);
namespace Symfony\component\httpfoundation;class response{Public function Send () {$this->sendheaders ();        $this->sendcontent ();        if (function_exists (' fastcgi_finish_request ')) {fastcgi_finish_request ();        } elseif (' CLI '!== php_sapi) {static::closeoutputbuffers (0, true);    } return $this;        }//Send headers to client public function sendheaders () {///headers has already been sent by the developer        if (Headers_sent ()) {return $this;            }//Headers foreach ($this->headers->allpreservecasewithoutcookies () as $name = = $values) {            foreach ($values as $value) {header ($name. ': '. $value, False, $this->statuscode); }}//Status header (sprintf (' http/%s%s ', $this->version, $this->statuscode, $this->stat        Ustext), True, $this->statuscode); Cookie foreach ($this->headers->getcookies () as $cookie) {if ($cookie->israw ()) {Setrawcookie ($cookie->getname (), $c Ookie->getvalue (), $cookie->getexpirestime (), $cookie->getpath (), $cookie->getdomain (), $cookie-            Issecure (), $cookie->ishttponly ()); } else {Setcookie ($cookie->getname (), $cookie->getvalue (), $cookie->getexpirestime (), $cookie-&gt            ; GetPath (), $cookie->getdomain (), $cookie->issecure (), $cookie->ishttponly ());    }} return $this;        }//Send response content to client public function sendcontent () {echo $this->content;    return $this; }}

sendThe logic is very good to understand, the previous set of those headers set to the HTTP Response header field, the content will echo after the HTTP response is set to the principal entity. Finally, PHP sends the full HTTP response to the client.

After the send response, HTTP kernel executes method calls to the method terminate in the Terminate middleware terminate , and finally executes the applied termiate method to end the entire application life cycle (from receiving the request to the end of the return response).

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.