src/Response.php
public function sendHeaders($replace = false, $callback = null)
    {
        $protocol = $this->protocol;
        $status = $this->status;
        $cookies = $this->cookie();
        $headers = $this->headers();

        Base::getLog()->debug(__METHOD__ . ' begin to send header', [
            'protocol' => $protocol,
            'status'   => $status,
            'header'   => $headers,
            'cookie'   => $cookies,
        ]);

        $renderHeaders = [$protocol . ' ' . $status . ' ' . Arr::get(Http::$text, $status)];

        foreach ($headers as $header => $value)
        {
            if (is_array($value))
            {
                $value = implode(', ', $value);
            }

            // 格式化header的key
            $header = explode('-', $header);
            foreach ($header as $k => $v)
            {
                $header[$k] = ucfirst($v);
            }
            $header = implode('-', $header);

            $renderHeaders[] = $header . ': ' . $value;
        }

        if (isset($headers['content-type']) || isset($headers['Content-Type']))
        {
            // 已经有content-type了，这里就不做处理了
        }
        else
        {
            // 默认content-type
            $renderHeaders[] = 'Content-Type: ' . Base::$contentType . '; charset=' . $this->charset;
        }

        if (Base::$expose && ! isset($headers['x-powered-by']))
        {
            $renderHeaders[] = 'X-Powered-By: ' . Base::version();
        }

        if ($cookies)
        {
            $renderHeaders['Set-Cookie'] = $cookies;
        }

        if (is_callable($callback))
        {
            // Use the callback method to set header
            return call_user_func($callback, $this, $renderHeaders, $replace);
        }
        else
        {
            $this->_sendHeadersToPhp($renderHeaders, $replace);

            return $this;
        }
    }
public function sendHeaders($replace = false, $callback = null)
    {
        $protocol = $this->protocol;
        $status = $this->status;
        $cookies = $this->cookie();
        $headers = $this->headers();

        Base::getLog()->debug(__METHOD__ . ' begin to send header', [
            'protocol' => $protocol,
            'status'   => $status,
            'header'   => $headers,
            'cookie'   => $cookies,
        ]);

        $renderHeaders = [$protocol . ' ' . $status . ' ' . Arr::get(Http::$text, $status)];

        foreach ($headers as $header => $value)
        {
            if (is_array($value))
            {
                $value = implode(', ', $value);
            }

            // 格式化header的key
            $header = explode('-', $header);
            foreach ($header as $k => $v)
            {
                $header[$k] = ucfirst($v);
            }
            $header = implode('-', $header);

            $renderHeaders[] = $header . ': ' . $value;
        }

        if (isset($headers['content-type']) || isset($headers['Content-Type']))
        {
            // 已经有content-type了，这里就不做处理了
        }
        else
        {
            // 默认content-type
            $renderHeaders[] = 'Content-Type: ' . Base::$contentType . '; charset=' . $this->charset;
        }

        if (Base::$expose && ! isset($headers['x-powered-by']))
        {
            $renderHeaders[] = 'X-Powered-By: ' . Base::version();
        }

        if ($cookies)
        {
            $renderHeaders['Set-Cookie'] = $cookies;
        }

        if (is_callable($callback))
        {
            // Use the callback method to set header
            return call_user_func($callback, $this, $renderHeaders, $replace);
        }
        else
        {
            $this->_sendHeadersToPhp($renderHeaders, $replace);

            return $this;
        }
    }
发送当前保存的header信息

@param  bool     $replace  替换已经存在的header
@param  callback $callback 是否自定义处理函数
@return $this