search
HomeBackend DevelopmentPHP Tutorial CI框架源码翻阅-Output.php

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

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * 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 ( ! empty($this->_profiler_sections))
			{
				$CI->profiler->set_sections($this->_profiler_sections);
			}

			// If the output data contains closing 
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
C语言return的用法详解C语言return的用法详解Oct 07, 2023 am 10:58 AM

C语言return的用法有:1、对于返回值类型为void的函数,可以使用return语句来提前结束函数的执行;2、对于返回值类型不为void的函数,return语句的作用是将函数的执行结果返回给调用者;3、提前结束函数的执行,在函数内部,我们可以使用return语句来提前结束函数的执行,即使函数并没有返回值。

入职后,我才明白什么叫Cache入职后,我才明白什么叫CacheJul 31, 2023 pm 04:03 PM

事情其实是这样的,当时领导交给我一个perf硬件性能监视的任务,在使用perf的过程中,输入命令perf list,我看到了以下信息:我的任务就要让这些cache事件能够正常计数,但关键是,我根本不知道这些misses、loads是什么意思。

修复:截图工具在 Windows 11 中不起作用修复:截图工具在 Windows 11 中不起作用Aug 24, 2023 am 09:48 AM

为什么截图工具在Windows11上不起作用了解问题的根本原因有助于找到正确的解决方案。以下是截图工具可能无法正常工作的主要原因:对焦助手已打开:这可以防止截图工具打开。应用程序损坏:如果截图工具在启动时崩溃,则可能已损坏。过时的图形驱动程序:不兼容的驱动程序可能会干扰截图工具。来自其他应用程序的干扰:其他正在运行的应用程序可能与截图工具冲突。证书已过期:升级过程中的错误可能会导致此issu简单的解决方案这些适合大多数用户,不需要任何特殊的技术知识。1.更新窗口和Microsoft应用商店应用程

Java中return和finally语句的执行顺序是怎样的?Java中return和finally语句的执行顺序是怎样的?Apr 25, 2023 pm 07:55 PM

源码:publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}}#输出上述代码的输出可以简单地得出结论:return在finally之前执行,我们来看下字节码层面上发生了什么事情。下面截取case1方法的部分字节码,并且对照源码,将每个指令的含义注释在

如何修复无法连接到iPhone上的App Store错误如何修复无法连接到iPhone上的App Store错误Jul 29, 2023 am 08:22 AM

第1部分:初始故障排除步骤检查苹果的系统状态:在深入研究复杂的解决方案之前,让我们从基础知识开始。问题可能不在于您的设备;苹果的服务器可能会关闭。访问Apple的系统状态页面,查看AppStore是否正常工作。如果有问题,您所能做的就是等待Apple修复它。检查您的互联网连接:确保您拥有稳定的互联网连接,因为“无法连接到AppStore”问题有时可归因于连接不良。尝试在Wi-Fi和移动数据之间切换或重置网络设置(“常规”>“重置”>“重置网络设置”>设置)。更新您的iOS版本:

使用cache可以提高计算机运行速度这是因为什么使用cache可以提高计算机运行速度这是因为什么Dec 09, 2020 am 11:28 AM

使用cache可以提高计算机运行速度这是因为Cache缩短了CPU的等待时间。Cache是位于CPU和主存储器DRAM之间,规模较小,但速度很高的存储器。Cache的功能是提高CPU数据输入输出的速率;Cache容量小但速度快,内存速度较低但容量大,通过优化调度算法,系统的性能会大大改善。

cache是什么存储器?cache是什么存储器?Nov 25, 2022 am 11:48 AM

cache叫做高速缓冲存储器,是介于中央处理器和主存储器之间的高速小容量存储器,一般由高速SRAM构成;这种局部存储器是面向CPU的,引入它是为减小或消除CPU与内存之间的速度差异对系统性能带来的影响。Cache容量小但速度快,内存速度较低但容量大,通过优化调度算法,系统的性能会大大改善。

SpringBoot项目中怎么使用缓存CacheSpringBoot项目中怎么使用缓存CacheMay 16, 2023 pm 02:34 PM

前言缓存可以通过将经常访问的数据存储在内存中,减少底层数据源如数据库的压力,从而有效提高系统的性能和稳定性。我想大家的项目中或多或少都有使用过,我们项目也不例外,但是最近在review公司的代码的时候写的很蠢且low,大致写法如下:publicUsergetById(Stringid){Useruser=cache.getUser();if(user!=null){returnuser;}//从数据库获取user=loadFromDB(id);cahce.put(id,user);returnu

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),