资讯专栏INFORMATION COLUMN

Laravel 响应准备

terro / 3344人阅读

摘要:响应准备若不是的对象,则构造成此对象类型本质就是用的类构建响应准备主要是设置响应头信息类设置编码格式若传输时用分块编码,则移除因为采用分块编码时可以知道传输何时完成

Laravel 响应准备
public function prepareResponse($request, $response)
{
    if ($response instanceof PsrResponseInterface) {
        $response = (new HttpFoundationFactory)->createResponse($response);
    }
    // 若不是 SymfonyComponentHttpFoundationSymfonyResponse 的对象,则构造成此对象
    elseif (! $response instanceof SymfonyResponse) {
        $response = new Response($response);
    }

    return $response->prepare($request);
}
PsrResponseInterface 类型
public function createResponse(ResponseInterface $psrResponse)
{
    $response = new Response(
        $psrResponse->getBody()->__toString(),
        $psrResponse->getStatusCode(),
        $psrResponse->getHeaders()
    );
    $response->setProtocolVersion($psrResponse->getProtocolVersion());

    foreach ($psrResponse->getHeader("Set-Cookie") as $cookie) {
        $response->headers->setCookie($this->createCookie($cookie));
    }

    return $response;
}

本质就是用的 Response 类
Response 构建
public function __construct($content = "", $status = 200, $headers = array())
{
    $this->headers = new ResponseHeaderBag($headers);
    $this->setContent($content);
    $this->setStatusCode($status);
    $this->setProtocolVersion("1.0");

    // Deprecations
    $class = get_class($this);
    if ($this instanceof PHPUnit_Framework_MockObject_MockObject || $this instanceof ProphecyDoublerDoubleInterface) {
        $class = get_parent_class($class);
    }
    if (isset(self::$deprecationsTriggered[$class])) {
        return;
    }

    self::$deprecationsTriggered[$class] = true;
    foreach (self::$deprecatedMethods as $method) {
        $r = new ReflectionMethod($class, $method);
        if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
            @trigger_error(sprintf("Extending %s::%s() in %s is deprecated since version 3.2 and won"t be supported anymore in 4.0 as it will be final.", __CLASS__, $method, $class), E_USER_DEPRECATED);
        }
    }
}
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;
}
public function setStatusCode($code, $text = null)
{
    $this->statusCode = $code = (int) $code;
    if ($this->isInvalid()) {
        throw new InvalidArgumentException(sprintf("The HTTP status code "%s" is not valid.", $code));
    }

    if (null === $text) {
        $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : "unknown status";

        return $this;
    }

    if (false === $text) {
        $this->statusText = "";

        return $this;
    }

    $this->statusText = $text;

    return $this;
}
public function isInvalid()
{
    return $this->statusCode < 100 || $this->statusCode >= 600;
}
public function setProtocolVersion($version)
{
    $this->version = $version;

    return $this;
}
响应准备

主要是设置响应头

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 {
        if (!$headers->has("Content-Type")) {
            $format = $request->getRequestFormat();
            # static::$formats = array(
            #    "html" => array("text/html", "application/xhtml+xml"),
            #    "txt" => array("text/plain"),
            #    "js" => array("application/javascript", "application/x-javascript", "text/javascript"),
            #    "css" => array("text/css"),
            #    "json" => array("application/json", "application/x-json"),
            #    "xml" => array("text/xml", "application/xml", "application/x-xml"),
            #    "rdf" => array("application/rdf+xml"),
            #    "atom" => array("application/atom+xml"),
            #    "rss" => array("application/rss+xml"),
            #    "form" => array("application/x-www-form-urlencoded"),
            # );
            if (null !== $format && $mimeType = $request->getMimeType($format)) {
                $headers->set("Content-Type", $mimeType);
            }
        }
        // 设置编码格式
        $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")) {
            $headers->set("Content-Type", $headers->get("Content-Type")."; charset=".$charset);
        }
        // 若传输时用分块编码,则移除 Content-Length, 因为采用分块编码时可以知道传输何时完成
        if ($headers->has("Transfer-Encoding")) {
            $headers->remove("Content-Length");
        }

        if ($request->isMethod("HEAD")) {
            $length = $headers->get("Content-Length");
            $this->setContent(null);
            if ($length) {
                $headers->set("Content-Length", $length);
            }
        }
    }

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

    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;
}
public function isInformational()
{
    return $this->statusCode >= 100 && $this->statusCode < 200;
}
protected function ensureIEOverSSLCompatibility(Request $request)
{
    if (false !== stripos($this->headers->get("Content-Disposition"), "attachment") && preg_match("/MSIE (.*?);/i", $request->server->get("HTTP_USER_AGENT"), $match) == 1 && true === $request->isSecure()) {
        if ((int) preg_replace("/(MSIE )(.*?);/", "$2", $match[0]) < 9) {
            $this->headers->remove("Cache-Control");
        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22614.html

相关文章

  • Laravel学习:请求到响应的生命周期

    摘要:请求处理阶段请求处理阶段首先是准备请求处理的环境,包括环境加载服务提供者注册等环节,然后将请求实例通过中间件处理及通过路由和控制器的分发控制,使得不同的请求通过相应的处理程序进行处理并生成响应的过程。 Laravel请求到响应的整个执行过程,主要可以归纳为四个阶段,即程序启动准备阶段、请求实例化阶段、请求处理阶段、响应发送和程序终止阶段。 程序启动准备阶段 服务容器实例化 服务容器的实...

    OBKoro1 评论0 收藏0
  • Laravel 请求周期

    摘要:请求周期加载自动加载器获取应用对象实例化应用解析此对象贯穿全文主要过程设置基础路径基础绑定注册全局基础服务核心容器别名设置注册三个单例获取对象实例化此对象为应用的枢纽,将会协调各部分之间的工作,完成请求主要过程注入应用对象注入事件对象注入 Laravel 请求周期 加载 composer 自动加载器 require __DIR__./../bootstrap/autoload.php;...

    Cristalven 评论0 收藏0
  • Laravel 启动流程

    摘要:年月日阶段划分请求到响应的整个执行阶段归纳为个程序启动准备阶段文件自动加载服务容器实例化基础服务提供者的注册核心类的实例化请求实例化阶段实例化实例请求处理阶段准备请求处理的环境将请求实例通过中间件处理及通过路由和控制器的分发控制响应发送和 Last-Modified: 2019年5月10日16:19:07 阶段划分 Laravel 5.5请求到响应的整个执行阶段归纳为 4 个: ...

    VPointer 评论0 收藏0
  • Laravel 开启跨域功能

    摘要:跨域的请求出于安全性的原因,浏览器会限制中的跨域请求。跨源共享标准需要浏览器和服务端共同配合才能完成,目前浏览器厂商已经可以将请求部分自动完成,所以跨源资源访问的重点还是在于服务器端。指明预请求或者跨域请求的来源。 跨域的请求 出于安全性的原因,浏览器会限制 Script 中的跨域请求。由于 XMLHttpRequest 遵循同源策略,所有使用 XMLHttpRequest 构造 HT...

    muzhuyu 评论0 收藏0
  • 从PHP Laravel 到 Go Iris--路由篇

    摘要:可以通过来直接设置路由前缀给添加前缀通过,还是通过就可以了匹配包含的匹配包含的好了,这两个框架的路由基本比较和应用就这些了,还有一些比如控制器路由和如何自定义中间件等在后续再写吧,或者请自行查阅文档,以上内容如有错误请指出。 Laravel是我最喜欢的PHP Web开发框架,所以也希望可以在Go的Web框架中选择一个类似Laravel这样的好用又全栈的框架,刷了一下Beego, Ech...

    lingdududu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<