Home >Backend Development >PHP Tutorial >CI framework source code reading---------Output.php_PHP tutorial

CI framework source code reading---------Output.php_PHP tutorial

WBOY
WBOYOriginal
2016-07-14 10:09:18938browse

[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
* Responsible for sending the final output to the 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
* Current output string
*
* @var string
* @access protected
*/  
    protected $final_output;  
    /**
* Cache expiration time
* Cache expiration time
* @var int
* @access protected
*/  
    protected $cache_expiration = 0;  
    /**
* List of server headers
* Server header list
* @var array
* @access protected
*/  
    protected $headers          = array();  
    /** 
     * List of mime types 
     *  
     * @var array 
     * @access  protected 
     */  
    protected $mime_types       = array();  
    /**
* Determines wether profiler is enabled
* Whether to enable the analyzer
* @var book
* @access protected
*/  
    protected $enable_profiler  = FALSE;  
    /**
* Determines if output compression is enabled
* Whether to enable output compression
* @var bool
* @access protected
*/  
    protected $_zlib_oc         = FALSE;  
    /**
* List of profiler sections
* Analyzer list
*
* @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()
{
// Return the value of the configuration item zlib.output_compression and assign it to $this->_zlib_oc
// If the output compression function is turned on in the configuration item, the value of $this->_zlib_oc is on
$this->_zlib_oc = @ini_get('zlib.output_compression');
// Get mime types for later
// Get 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 is an array defined in mimes.php
$this->mime_types = $mimes;
log_message('debug', "Output Class Initialized");
}
//------------------------------------------------ -----------------------
/**
* Get Output
* Using this method, you can get the data to be output and save it
* Returns the current output string
* Returns the current output string
* @access public
* @return string
*/
function get_output()
{
return $this->final_output;
}
//------------------------------------------------ -----------------------
/**
* Set Output
*
* Sets the output string
* Set the output string
* @access public
* @param string
* @return void
*/
function set_output($output)
{
$this->final_output = $output;
return $this;
}
//------------------------------------------------ -----------------------
/**
* Append Output
* After the final output string, append data
* 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
* Using this method, allows you to set the header of the HTTP protocol that will be sent to the browser, which is equivalent to the standard function of PHP: header().
* Lets you set a server header which will be outputted with the final display.
* Allows you to set a server header for final display output.
* 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
* Allows you to enable or disable the analyzer
* @access public
* @param bool
* @return void
*/  
    function enable_profiler($val = TRUE)  
    {  
        $this->enable_profiler = (is_bool($val)) ? $val : TRUE;  
  
        return $this;  
    }  
  
    // --------------------------------------------------------------------  
  
    /**
* Set Profiler Sections
* Set $this->_profiler_sections
* Allows override of default / config settings for Profiler section display
* Allows you to control (on/off) specific parts of the reviewer when it is enabled
*
* @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
* Set cache and cache time
* @access public
* @param integer where $time is the number of minutes you want the cache to be updated
* @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.
// Note: We use global because we cannot use $CI =& get_instance()
global $BM, $CFG;
// Grab the super object if we can.
// //Of course, if we can get the super controller, we’ll get it first.
if (class_exists('CI_Controller'))
{
$CI =& get_instance();
} }
// --------------------------------------------- -----------------------
// Set the output data
// Set 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
// If the cache time>0, the $CI super object exists and the _output method exists under the super object
// Call the _write_cache method to write a cache file
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
// Calculate code execution time and memory usage time
$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
// If $this->parse_exec_vars is true, {elapsed_time}, {memory_usage} in the output will be output
// Replace with the calculated time.
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? Processing of compression transmission.
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 and tags  
            // we will remove them and add them back after we insert the profile data  
            // 如果存在标签,我们将删除,插入我们的性能分析代码后再添加回去  
            if (preg_match("|.*?|is", $output))  
            {  
                $output  = preg_replace("|.*?|is", '', $output);  
                $output .= $CI->profiler->run();  
$output .= '';
      }  
        else  
                                                                 
$output .= $CI->profiler->run();
      }  
} }
// --------------------------------------------- -----------------------
// Does the controller contain a function named _output()?
// If so send the output there. Otherwise, echo it.
// If there is _output method in the controller, we call it directly
// If data is not sent directly to the browser
if (method_exists($CI, '_output'))
{
$CI->_output($output);
} }
else
{
echo $output; // Send it to the browser!
} }
log_message('debug', "Final output sent to browser");
log_message('debug', "Total execution time: ".$elapsed);
}
//------------------------------------------------ -----------------------
/**
* Write a Cache File
* Generate a cache file
* @access public
* @param string
* @return void
*/
function _write_cache($output)
{
// Call super object
$CI =& get_instance();
// Find the cache path
$path = $CI->config->item('cache_path');
$cache_path = ($path == '') ? APPPATH.'cache/' : $path;
// If the cache path is not a folder or cannot be written, an error will be returned.
if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
{
log_message('error', "Unable to write cache file: ".$cache_path);
return;
} }
// Get $uri
$uri = $CI->config->item('base_url').
$CI->config->item('index_page').
$CI->uri->uri_string();
// Generate cache file.
$cache_path .= md5($uri);
if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
{
log_message('error', "Unable to write cache file: ".$cache_path);
return;
} }
// Calculate cache file expiration time.
$expire = time() + ($this->cache_expiration * 60);
if (flock($fp, LOCK_EX))
        {  
            fwrite($fp, $expire.'TS--->'.$output);  
            flock($fp, LOCK_UN);  
        }  
        else  
        {  
            log_message('error', "Unable to secure a file lock for file at: ".$cache_path);  
            return;  
        }  
        fclose($fp);  
        @chmod($cache_path, FILE_WRITE_MODE);  
  
        log_message('debug', "Cache file written: ".$cache_path);  
    }  
  
    // --------------------------------------------------------------------  
  
    /**
* Update/serve a cached file
* This method is called in CodeIgniter.php. This method is responsible for caching the output.
* If there is output when calling this method in CodeIgniter.php, then
* The execution of this request will end directly and the cached output will be responded directly.
*
* @access public
* @param object config class
* @param object uri class
* @return void
*/  
    function _display_cache(&$CFG, &$URI)  
    {  
        // 取得保存缓存的路径  
        $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');  
  
        // Build the file path.  The file name is an MD5 hash of the full URI  
        // 一条准确的路由都会对应一个缓存文件,缓存文件是对应路由字符串的md5密文。  
        $uri =  $CFG->item('base_url').  
                $CFG->item('index_page').  
                $URI->uri_string;  
  
        $filepath = $cache_path.md5($uri);  
  
        // 如果没有此缓存文件,获取缓存内容失败,则可以返回FALSE。  
        if ( ! @file_exists($filepath))  
        {  
            return FALSE;  
        }  
        // 如果有此缓存文件,但是无法读,获取缓存内容失败,同样返回FALSE。  
        if ( ! $fp = @fopen($filepath, FOPEN_READ))  
        {  
            return FALSE;  
        }  
  
        // 打开到缓存文件,并以$fp作为句柄。下一步先取得共享锁(读取)。  
        flock($fp, LOCK_SH);  
  
        $cache = '';  
        if (filesize($filepath) > 0)  
        {  
            $cache = fread($fp, filesize($filepath));  
        }  
        // 解锁  
        flock($fp, LOCK_UN);  
        // 关闭文件连接。  
        fclose($fp);  
  
        // 下面这个TS--->字样,只是因为CI的缓存文件里面的内容  
        // 是规定以数字+TS--->开头而已。这个数字是代表创建时间。  
// If it does not conform to this structure, it can be regarded as a non-CI cache file, or the file is damaged,
// Failed to obtain the cache content and returns FALSE.
// Strip out the embedded timestamp
if ( ! preg_match("/(d+TS--->)/", $cache, $match))
{
return FALSE;
} }
// Has the file expired? If so we'll delete it.
// Determine whether the cache has expired, if it expires we will delete it
if (time() >= trim(str_replace('TS--->', '', $match['1'])))
{
if (is_really_writable($cache_path))
                                                                 
              @unlink($filepath);  
Log_message('debug', "Cache file has expired. File deleted");
return FALSE;
      }  
} }
// Display the cache
$this->_display(str_replace($match['0'], '', $cache));
log_message('debug', "Cache file is current. Sending it to browser.");
return TRUE;
}
}
// END Output Class
/* End of file Output.php */
/* Location: ./system/core/Output.php */

http://www.bkjia.com/PHPjc/477678.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/477678.htmlTechArticle[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 * * @packag...
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