欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

CI框架源码阅读---------Output.php

程序员文章站 2022-06-13 08:48:26
...
[php]

/**

* CodeIgniter

*

* An open source application development framework for PHP 5.1.6 or newer

*

* @package CodeIgniter

* @author ExpressionEngine Dev Team

* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.

* @license http://codeigniter.com/user_guide/license.html

* @link http://codeigniter.com

* @since Version 1.0

* @filesource

*/

// ------------------------------------------------------------------------

/**

* Output Class

*

* Responsible 负责 for sending final output to browser

* 负责把最终的输出发送到浏览器

* @package CodeIgniter

* @subpackage Libraries

* @category Output

* @author ExpressionEngine Dev Team

* @link http://codeigniter.com/user_guide/libraries/output.html

*/

class CI_Output {

/**

* Current output string

* 当前输出的字符串

*

* @var string

* @access protected

*/

protected $final_output;

/**

* Cache expiration time

* 缓存终结的时间

* @var int

* @access protected

*/

protected $cache_expiration = 0;

/**

* List of server headers

* 服务器头列表

* @var array

* @access protected

*/

protected $headers = array();

/**

* List of mime types

*

* @var array

* @access protected

*/

protected $mime_types = array();

/**

* Determines wether profiler is enabled

* 是否启用分析器

* @var book

* @access protected

*/

protected $enable_profiler = FALSE;

/**

* Determines if output compression is enabled

* 是否开启输出压缩

* @var bool

* @access protected

*/

protected $_zlib_oc = FALSE;

/**

* List of profiler sections

* 分析器列表

*

* @var array

* @access protected

*/

protected $_profiler_sections = array();

/**

* Whether or not to parse variables like {elapsed_time} and {memory_usage}

* 是否解析变量{elapsed_time} and {memory_usage}

* 注意文档说这里有错误详见http://codeigniter.org.cn/user_guide/libraries/output.html

* 最下方

* @var bool

* @access protected

*/

protected $parse_exec_vars = TRUE;

/**

* Constructor

*

*/

function __construct()

{

// 返回配置项zlib.output_compression的值并赋给$this->_zlib_oc

// 如果配置项中开启了输出压缩功能则 $this->_zlib_oc 的值为on

$this->_zlib_oc = @ini_get('zlib.output_compression');

// Get mime types for later

// 获取mimetype

if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))

{

include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';

}

else

{

include APPPATH.'config/mimes.php';

}

// $mimes 是mimes.php中定义的一个数组

$this->mime_types = $mimes;

log_message('debug', "Output Class Initialized");

}

// --------------------------------------------------------------------

/**

* Get Output

* 使用这个方法,你可以得到将要输出的数据,并把它保存起来

* Returns the current output string

* 返回当前输出的字符串

* @access public

* @return string

*/

function get_output()

{

return $this->final_output;

}

// --------------------------------------------------------------------

/**

* Set Output

*

* Sets the output string

* 设置输出的字符串

* @access public

* @param string

* @return void

*/

function set_output($output)

{

$this->final_output = $output;

return $this;

}

// --------------------------------------------------------------------

/**

* Append Output

* 在最终输出字符串后,追加数据

* Appends data onto the output string

*

* @access public

* @param string

* @return void

*/

function append_output($output)

{

if ($this->final_output == '')

{

$this->final_output = $output;

}

else

{

$this->final_output .= $output;

}

return $this;

}

// --------------------------------------------------------------------

/**

* Set Header

* 使用此方法,允许你设置将会被发送到浏览器的HTTP协议的标头,作用相当于php的标准函数: header()。

* Lets you set a server header which will be outputted with the final display.

* 允许您设置一个服务器头用于最终的显示输出。

* Note: If a file is cached, headers will not be sent. We need to figure 计算 out

* how to permit header data to be saved with the cache data...

*

* @access public

* @param string

* @param bool

* @return void

*/

function set_header($header, $replace = TRUE)

{

// If zlib.output_compression is enabled it will compress the output,

// but it will not modify the content-length header to compensate 补偿 for

// the reduction减少 还原, causing the browser to hang waiting for more data.

// We'll just skip content-length in those cases.

if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)

{

return;

}

$this->headers[] = array($header, $replace);

return $this;

}

// --------------------------------------------------------------------

/**

* Set Content Type Header

* 设置Content-Type

* @access public

* @param string extension of the file we're outputting

* @return void

*/

function set_content_type($mime_type)

{

if (strpos($mime_type, '/') === FALSE)

{

$extension = ltrim($mime_type, '.');

// Is this extension supported?

if (isset($this->mime_types[$extension]))

{

$mime_type =& $this->mime_types[$extension];

if (is_array($mime_type))

{

$mime_type = current($mime_type);

}

}

}

$header = 'Content-Type: '.$mime_type;

$this->headers[] = array($header, TRUE);

return $this;

}

// --------------------------------------------------------------------

/**

* Set HTTP Status Header

* moved to Common procedural functions in 1.7.2

* 允许你手动设置服务器状态头(header)

* @access public

* @param int the status code

* @param string

* @return void

*/

function set_status_header($code = 200, $text = '')

{

set_status_header($code, $text);

return $this;

}

// --------------------------------------------------------------------

/**

* Enable/disable Profiler

* 允许你开启或禁用分析器

* @access public

* @param bool

* @return void

*/

function enable_profiler($val = TRUE)

{

$this->enable_profiler = (is_bool($val)) ? $val : TRUE;

return $this;

}

// --------------------------------------------------------------------

/**

* Set Profiler Sections

* 设置$this->_profiler_sections

* Allows override of default / config settings for Profiler section display

* 允许你在评测器启用时,控制(开/关)其特定部分

*

* @access public

* @param array

* @return void

*/

function set_profiler_sections($sections)

{

foreach ($sections as $section => $enable)

{

$this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;

}

return $this;

}

// --------------------------------------------------------------------

/**

* Set Cache

* 设置缓存以及缓存时间

* @access public

* @param integer 其中 $time 是你希望缓存更新的 分钟 数

* @return void

*/

function cache($time)

{

$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;

return $this;

}

// --------------------------------------------------------------------

/**

* Display Output

* 显示输出

* All "view" data is automatically put into this variable by the controller class:

*

* $this->final_output

*

* This function sends the finalized output data to the browser along

* with any server headers and profile data. It also stops the

* benchmark timer so the page rendering speed and memory usage can be shown.

*

* @access public

* @param string

* @return mixed

*/

function _display($output = '')

{

// Note: We use globals because we can't use $CI =& get_instance()

// since this function is sometimes called by the caching mechanism,

// which happens before the CI super object is available.

// 注意:我们使用global 是因为我们不能使用$CI =& get_instance()

global $BM, $CFG;

// Grab the super object if we can.

// //当然如果可以拿到超级控制器,我们先拿过来。

if (class_exists('CI_Controller'))

{

$CI =& get_instance();

}

// --------------------------------------------------------------------

// Set the output data

// 设置输出数据

if ($output == '')

{

$output =& $this->final_output;

}

// --------------------------------------------------------------------

// Do we need to write a cache file? Only if the controller does not have its

// own _output() method and we are not dealing with a cache file, which we

// can determine by the existence of the $CI object above

// 如果缓存时间>0 ,$CI 超级对象存在并且超级对象下面存在_output 方法

// 调用_write_cache 方法,写一个缓存文件

if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))

{

$this->_write_cache($output);

}

// --------------------------------------------------------------------

// Parse out the elapsed time and memory usage,

// then swap the pseudo-variables with the data

// 计算代码执行时间和内存使用时间

$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');

// 如果$this->parse_exec_vars为true,将输出中的{elapsed_time},{memory_usage}

// 替换为计算出的时间。

if ($this->parse_exec_vars === TRUE)

{

$memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';

$output = str_replace('{elapsed_time}', $elapsed, $output);

$output = str_replace('{memory_usage}', $memory, $output);

}

// --------------------------------------------------------------------

// Is compression requested?压缩传输的处理。

if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)

{

if (extension_loaded('zlib'))

{

if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)

{

ob_start('ob_gzhandler');

}

}

}

// --------------------------------------------------------------------

// Are there any server headers to send?

// 有没有服务器头发送?

if (count($this->headers) > 0)

{

foreach ($this->headers as $header)

{

@header($header[0], $header[1]);

}

}

// --------------------------------------------------------------------

// Does the $CI object exist?

// If not we know we are dealing with a cache file so we'll

// simply echo out the data and exit.

// 如果没有$CI就证明当前是一个缓存的输出,我们只简单的发送数据并退出

if ( ! isset($CI))

{

echo $output;

log_message('debug', "Final output sent to browser");

log_message('debug', "Total execution time: ".$elapsed);

return TRUE;

}

// --------------------------------------------------------------------

// Do we need to generate profile data?

// If so, load the Profile class and run it.

// 如果开启了性能分析我们就调用,

// 会生成一些报告到页面尾部用于辅助我们调试。

if ($this->enable_profiler == TRUE)

{

$CI->load->library('profiler');

if ( ! emptyempty($this->_profiler_sections))

{

$CI->profiler->set_sections($this->_profiler_sections);

}

// If the output data contains closing