上一节介绍了基本的HTTP协议知识,这里介绍在CI中和HTTP协议相关的方法。

set_status_header

if ( ! function_exists('set_status_header'))
{
    // 设定响应行
    function set_status_header($code = 200, $text = '')
    {
        if (is_cli())
        {
            return;
        }

        if (empty($code) OR ! is_numeric($code))
        {
            show_error('Status codes must be numeric', 500);
        }

        // 提供默认的原因短语
        if (empty($text))
        {
            is_int($code) OR $code = (int) $code;
            $stati = array(
                100    => 'Continue',
                101    => 'Switching Protocols',

                200    => 'OK',
                201    => 'Created',
                202    => 'Accepted',
                203    => 'Non-Authoritative Information',
                204    => 'No Content',
                205    => 'Reset Content',
                206    => 'Partial Content',

                300    => 'Multiple Choices',
                301    => 'Moved Permanently',
                302    => 'Found',
                303    => 'See Other',
                304    => 'Not Modified',
                305    => 'Use Proxy',
                307    => 'Temporary Redirect',

                400    => 'Bad Request',
                401    => 'Unauthorized',
                402    => 'Payment Required',
                403    => 'Forbidden',
                404    => 'Not Found',
                405    => 'Method Not Allowed',
                406    => 'Not Acceptable',
                407    => 'Proxy Authentication Required',
                408    => 'Request Timeout',
                409    => 'Conflict',
                410    => 'Gone',
                411    => 'Length Required',
                412    => 'Precondition Failed',
                413    => 'Request Entity Too Large',
                414    => 'Request-URI Too Long',
                415    => 'Unsupported Media Type',
                416    => 'Requested Range Not Satisfiable',
                417    => 'Expectation Failed',
                422    => 'Unprocessable Entity',
                426    => 'Upgrade Required',
                428    => 'Precondition Required',
                429    => 'Too Many Requests',
                431    => 'Request Header Fields Too Large',

                500    => 'Internal Server Error',
                501    => 'Not Implemented',
                502    => 'Bad Gateway',
                503    => 'Service Unavailable',
                504    => 'Gateway Timeout',
                505    => 'HTTP Version Not Supported',
                511    => 'Network Authentication Required',
            );

            if (isset($stati[$code]))
            {
                $text = $stati[$code];
            }
            else
            {
                show_error('No status text available. Please check your status code number or supply your own message text.', 500);
            }
        }

        if (strpos(PHP_SAPI, 'cgi') === 0)
        {
            header('Status: '.$code.' '.$text, TRUE);
            return;
        }

        // 响应行的协议版本
        $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE))
            ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';

        // 设定响应行
        header($server_protocol.' '.$code.' '.$text, TRUE, $code);
    }
}

这个方法作用是设定响应行的三个基本信息:HTTP协议版本、状态码、原因短语。

在Output类上也有个同名方法,实质就是别名。

get_mimes

if ( ! function_exists('get_mimes'))
{
    // 获取mime对应的配置文件
    function &get_mimes()
    {
        static $_mimes;

        if (empty($_mimes))
        {
            $_mimes = file_exists(APPPATH.'config/mimes.php')
                ? include(APPPATH.'config/mimes.php')
                : array();

            if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
            {
                $_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'));
            }
        }

        return $_mimes;
    }
}

这个方法和get_config方法基本雷同,相当于mime版的get_config。它把加载的结果缓存到了静态变量$_mimes中。这个方法会在Output类的构造函数中用到。

set_header

```php set_header public function set_header($header, $replace = TRUE) { if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0) { return $this; }

// 缓存要输出的响应头
$this->headers[] = array($header, $replace);
return $this;

}


这个方法是Output类中的方法,用于设定要输出的响应头

## get_header

```php
public function get_header($header)
{
    // Combine headers already sent with our batched headers
    $headers = array_merge(
        array_map('array_shift', $this->headers),
        headers_list()
    );

    if (empty($headers) OR empty($header))
    {
        return NULL;
    }

    for ($c = count($headers) - 1; $c > -1; $c--)
    {
        if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0)
        {
            return trim(self::substr($headers[$c], $l+1));
        }
    }

    return NULL;
}

这个方法用来获取某个特定的响应头。headers_list方法用来获取已经输出的响应头字段,它与我们缓存在属性$headers中的字段合并后得到当前的响应头部字段,然后我们遍历找到最新的响应头部字段。

set_content_type

public function set_content_type($mime_type, $charset = NULL)
{
    // mime类型 结构是 主类型/子类型 ,如果传入的$mime_type不含 / 则需要根据配置文件设定
    if (strpos($mime_type, '/') === FALSE)
    {
        $extension = ltrim($mime_type, '.');
        if (isset($this->mimes[$extension]))
        {
            // get_mimes方法的结果,缓存到了Output类的$mimes中
            $mime_type =& $this->mimes[$extension];

            if (is_array($mime_type))
            {
                $mime_type = current($mime_type);
            }
        }
    }

    $this->mime_type = $mime_type;

    if (empty($charset))
    {
        $charset = config_item('charset');
    }

    $header = 'Content-Type: '.$mime_type
        .(empty($charset) ? '' : '; charset='.$charset);

    // 最终是缓存到Output的$headers上
    $this->headers[] = array($header, TRUE);
    return $this;
}

get_content_type

public function get_content_type()
{
    for ($i = 0, $c = count($this->headers); $i < $c; $i++)
    {
        if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1)
        {
            return $content_type;
        }
    }

    return 'text/html';
}

这个方法返回当前使用的mime类型,与set_content_type方法相呼应,但问题是我们已经使用属性$mime_type来表明当前类型了,为啥不直接返回该属性呢?

results matching ""

    No results matching ""