五十一、逐行阅读Yii2.0.43_Yii框架文件yii\web\Response.php(3)

一、send方法,发送响应

    // 发送响应数据到客户端
    public function send()
    {
        // 已经发送,直接返回
        if ($this->isSent) {
            return;
        }

        // 响应发送前事件处理
        $this->trigger(self::EVENT_BEFORE_SEND);

        // 准备阶段
        $this->prepare();
        //准备阶段结束后事件
        $this->trigger(self::EVENT_AFTER_PREPARE);

        //发送头
        $this->sendHeaders();
        //发送内容
        $this->sendContent();

        // 响应发送后事件
        $this->trigger(self::EVENT_AFTER_SEND);

        //设置标志
        $this->isSent = true;
    }

二、clear方法,清除数据

    // 清除数据
    public function clear()
    {
        $this->_headers = null;
        $this->_cookies = null;
        $this->_statusCode = 200;
        $this->statusText = 'OK';
        $this->data = null;
        $this->stream = null;
        $this->content = null;
        $this->isSent = false;
    }

三、sendHeaders方法,发送响应头

    // 发送响应头到客户端
    protected function sendHeaders()
    {
        // 检查响应头是否已经发送了
        if (headers_sent($file, $line)) {
            throw new HeadersAlreadySentException($file, $line);
        }

        if ($this->_headers) {
            foreach ($this->getHeaders() as $name => $values) {
                $name = str_replace(
                    ' ',
                    '-',
                    ucwords(// 每个词的首字母大写
                        str_replace('-', ' ', $name)
                    )
                );

                // 设置允许发送相同的头多次
                // set replace for first occurrence of header but false afterwards to allow multiple
                $replace = true;
                foreach ($values as $value) {
                    header("$name: $value", $replace);
                    $replace = false;
                }
            }
        }

        // 获取响应码并发送
        $statusCode = $this->getStatusCode();
        header("HTTP/{$this->version} {$statusCode} {$this->statusText}");

        //发送cookie
        $this->sendCookies();
    }

四、sendCookies方法,发送cookie

    // 发送cookie到客户端
    protected function sendCookies()
    {
        // cookie为空,返回
        if ($this->_cookies === null) {
            return;
        }

        // 返回request对象
        $request = Yii::$app->getRequest();

        // 是否启用cookie验证
        if ($request->enableCookieValidation) {
            if ($request->cookieValidationKey == '') {
                throw new InvalidConfigException(get_class($request) . '::cookieValidationKey must be configured with a secret key.');
            }
            $validationKey = $request->cookieValidationKey;
        }

        // CookieCollection实现了IteratorAggregate接口
        foreach ($this->getCookies() as $cookie) {
            $value = $cookie->value;

            //cookie校验
            if ($cookie->expire != 1 && isset($validationKey)) {
                $value = Yii::$app->getSecurity()->hashData(serialize([$cookie->name, $value]), $validationKey);
            }

            // php>=7.3.0
            if (PHP_VERSION_ID >= 70300) {
                setcookie($cookie->name, $value, [
                    'expires' => $cookie->expire,
                    'path' => $cookie->path,
                    'domain' => $cookie->domain,
                    'secure' => $cookie->secure,
                    'httpOnly' => $cookie->httpOnly,
                    'sameSite' => !empty($cookie->sameSite) ? $cookie->sameSite : null,
                ]);
            } else {
                // Work around for setting sameSite cookie prior PHP 7.3
                // https://stackoverflow.com/questions/39750906/php-setcookie-samesite-strict/46971326#46971326
                $cookiePath = $cookie->path;
                if (!is_null($cookie->sameSite)) {
                    $cookiePath .= '; samesite=' . $cookie->sameSite;
                }
                setcookie($cookie->name, $value, $cookie->expire, $cookiePath, $cookie->domain, $cookie->secure, $cookie->httpOnly);
            }
        }
    }

五、sendContent方法,发送内容

    //发送响应内容到客户端
    protected function sendContent()
    {
        if ($this->stream === null) {
            echo $this->content;

            return;
        }

        // Try to reset time limit for big files
        if (!function_exists('set_time_limit') || !@set_time_limit(0)) {
            Yii::warning('set_time_limit() is not available', __METHOD__);
        }

        if (is_callable($this->stream)) {
            $data = call_user_func($this->stream);
            foreach ($data as $datum) {
                echo $datum;
                flush();
            }
            return;
        }

        $chunkSize = 8 * 1024 * 1024; // 8MB per chunk

        if (is_array($this->stream)) {
            list($handle, $begin, $end) = $this->stream;

            // only seek if stream is seekable
            if ($this->isSeekable($handle)) {
                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);
        }
    }

总结:

 阅读了5个方法:

  • send方法,发送响应
  • clear方法,清除数据
  • sendHeaders方法,发送响应头
  • sendCookies方法,发送cookie
  • sendContent方法,发送内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值