专栏首页写PHP的老王细读Yii2的Response

细读Yii2的Response

细读Yii2的Response

一个完整的网络请求,最后都需要一个符合协议的返回。Yii2在处理web请求之后,统一通过web/Response处理返回。错误也会经过错误处理返回一个Response。

一个Response完整的流程有哪些?

  1. 创建Response对象,设置Resonse响应格式json,html,xml等
  2. 触发前置事件,暴露操给开发者在输出前对数据进行调整等
  3. 数据格式化。将所有response的内容更加输出格式转换成响应的字符串,并确定http返回码。
  4. 设置响应头。输出所有自定会返回头和标注http协议返回头。
  5. 输出内容。将字符串内容输出,并刷新缓冲区
  6. 触发后置事件。触发Response后置操作
  7. 数据清理

Yii2的Response

http状态码明确。在web/Response 文件中定义了状态码数组,几乎涵盖了所有的http状态码,并给出了标注的状态码文字说明。如果想了解http状态码,看Yii2的Response文件就足够了。

支持多种方式文件输出。sendFile 下载文件,sendContentAsFile将内容以文件的方式发送给客户端,xSendFile文件下载。

发送文件每次最多读取8M数据,防止占用过大内存

数据格式,支持多种数据格式html,json,xml并可以指定ResponseFormatter对数据格式进行扩展

Cookie处理,Yii2的请求Cooke由Request处理,但是响应Cookie由Response处理。这个相对于Thinkphp5 以及其他框架而言不一样。但是这种分工明确的设计却又很清晰明了。

总的而言,Yii2的Response 代码逻辑结构相当清晰,而且输出内容都非常规范的遵循http协议规范。同时提供前置事件,数据准备前置事件,后置事件给开发者在不同的情况下处理额外的数据。代码在阅读起来非常明了。从头到尾,完整的看一遍,就可以完全理解。以下是Response中的两段代码。

输出内容代码
    protected function sendContent()
    {
        if ($this->stream === null) {
            echo $this->content;

            return;
        }
        set_time_limit(0); // Reset time limit for big files
        $chunkSize = 8 * 1024 * 1024; // 8MB per chunk
        if (is_array($this->stream)) {
            list ($handle, $begin, $end) = $this->stream;
            fseek($handle, $begin);
            while (!feof($handle) && ($pos = ftell($handle)) <= $end) {
                if ($pos + $chunkSize > $end) {
                    $chunkSize = $end - $pos + 1;
                }
                echo fread($handle, $chunkSize);
                flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
            }
            fclose($handle);
        } else {
            while (!feof($this->stream)) {
                echo fread($this->stream, $chunkSize);
                flush();
            }
            fclose($this->stream);
        }
    }

没有什么特殊的。如果是简单的字符串,直接echo。主要看它处理stream的情况。

首先设置超时时间。对于读取文件流,没办法确定文件读取需要的时间,因此设置超时时间很必要。

设置最大读取长度。每个请求都需要占用一定的内存去处理数据。为了避免我限制申请内存造成php程序报内存不足,因此对于文件读取程序,必须设置读取限制。读取完及时刷新出去。

下载文件请求头设置
public function setDownloadHeaders($attachmentName, $mimeType = null, $inline = false, $contentLength = null)
    {
        $headers = $this->getHeaders();

        $disposition = $inline ? 'inline' : 'attachment';
        $headers->setDefault('Pragma', 'public')
            ->setDefault('Accept-Ranges', 'bytes')
            ->setDefault('Expires', '0')
            ->setDefault('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
            ->setDefault('Content-Disposition', $this->getDispositionHeaderValue($disposition, $attachmentName));

        if ($mimeType !== null) {
            $headers->setDefault('Content-Type', $mimeType);
        }

        if ($contentLength !== null) {
            $headers->setDefault('Content-Length', $contentLength);
        }

        return $this;
    }

想要输出一个下载文件的响应,Yii2的输出请求头中有以下内容:

  • Pragma:public 非必须
  • Expires:0 非必须
  • Cache-Control:must-revalidate, post-check=0, pre-check=0 非必须
  • Content-Disposition:文件名必须
  • Accept-Ranges:bytes 必须
  • Content-Type:文件mime 必须
  • Content-Length:文件长度 必须 设置完请求头之后就可以把内容输出。浏览器就会弹出一个下载提示框。

本文分享自微信公众号 - 写PHP的老王(laowang_php),作者:写PHP的老王

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Laravel 如何实现数据的软删除

    对于任何一个模型,如果需要使用软删除功能,需要在模型中使用 Illuminate\Database\Eloquent\SoftDeletes这个 trait。软...

    写PHP的老王
  • Laravel 参数验证的疑与惑

    Laravel 文档调用验证器,除了通过控制器,还有就是通过Facades的方式创建验证器对象。Validator::make($data,$rule,$mes...

    写PHP的老王
  • 不知不觉踩到PHP内存泄漏的雷

    最近工作上需要排查php频繁达到内存限制进程被杀掉的原因。项目中使用php写一个死循环,把mysql的数据同步到mq或者mongodb当中。内存问题主要出现在m...

    写PHP的老王
  • 专访 | Recurrent AI:呼叫系统的「变废为宝」

    自然语言处理是一个庞大的领域,比如普通文本与对话就是两个不同的领域,对话领域里,任务型对话又不同于闲聊型对话,问答式对话又不同于协作型对话……

    机器之心
  • MultiPoseNet:人体检测、姿态估计、语义分割一“网”打尽

    来自中东科技大学在ECCV2018会议上已录用的文章“MultiPoseNet: Fast Multi-Person Pose Estimation using...

    CV君
  • Python-Django

    一般在urls.py中配置url,在models.py中配置model,在views.py中配置View。

    py3study
  • 高防服务器除了DDOS防御外还可能会存在哪些不稳定因素?

    在移动互联网的时代,我们的生活,工作处处皆是离不开互联网。其中包括网络、底层的基础设施以及各种电子产品。在现下阶段不论大小的网站、游戏、APP都会存在DDoS攻...

    墨者安全科技
  • AI识别二次元妹子「绝对领域」,双马尾、超短裙、长筒袜也能检测 | 开源+线上玩

    有一只AI,名叫Deep Danbooru,专门用来审视二次元妹子身上的各种特征。

    量子位
  • TransactionScope事务处理方法介绍及.NET Core中的注意事项

    今天在写CzarCms的UnitOfWork的使用使用到了这个TransactionScope事务,因此对它进行了相关资料的查阅并记录如下,希望对大伙在.NET...

    依乐祝
  • Django入门(1)

    py3study

扫码关注云+社区

领取腾讯云代金券