Learn PHP Advanced development skills from CI source--codeigniter Framework Source Depth Analysis (4): Output class output.php

Source: Internet
Author: User
Tags benchmark flock learn php codeigniter

Output Class Reference description (Excerpt CI manual):
In general, you may not notice the output class at all, because it is completely transparent to you without your intervention. For example, when you use the loader to load a view file, it is automatically passed in to the output class and is automatically called by CodeIgniter at the end of the system execution. Still, you can handle the output manually when you need it.

say a few knowledge points and programming tips before you say the output class:
$_server[' http_accept_encoding '. The corresponding request header is accept-encoding: "gzip, deflate"
$_server[' Http_if_modified_since '. The corresponding request header is if-modified-since: "Sat, 08:10:03 GMT"
$_server[' Request_time '. Request Initiation Time
Knowledge Points:
1, cache: "Talking about the implementation of several levels of code-level Web Caching"
2, compression: "Three ways to achieve Web compression: Web server (nginx/apache), PHP extension, PHP code"
Tips:
In the code you want to implement this method of continuous invocation of class methods, only the end of each method to add a return $this;
$output
->set_content_type (' Application/json ')

->set_output (Json_encode (Array (' foo ' = ' bar '));

Public Function Set_content_type ($mime _type, $charset = NULL)

{
......
return $this;
}

CI To enable caching, add a sentence within the Controller's method (function): $this->output->cache (n), where n is the number of minutes the cache is updated.
The main function of the output class is responsible for outputting the final result to the browser, which includes loading the content output from the cache, content output based on the Controller method, including write cache, setting header information, loading the CI internal parser, and describing the structure and method property functions as follows:

now focus on the main member approach:
First, constructor __construct (): $_compress_output and $mimes values are started

1. Set the compression tag $_compress_output:
In the constructor, CI obtains whether gzip compression is turned on in the current PHP environment through Ini_get (' zlib.output_compression '). If the PHP environment is not turned on, then determine the configuration file compression settings (compress_output=true), is not required frame compression output, if required, as long as the current PHP is loaded zlib extension, then the $_compress_ The output tag is set to true.
In general, we will turn on the compression function of the Web server while using, and turn off the compression function of the program itself.
2. Set the $mimes value: Load the MIME information in the configuration application/config/mimes.php.


the output function cluster, which sets or gets the value of the member variable $final_output
Get_output ()
Get $this->final_output
Allows you to manually get the content that is stored in the output class for outgoing. Examples of Use:
$string = $this->output->get_output ();
Note that only data that is set by a method of the CodeIgniter output class, such as the $this->load->view () method, can be obtained using this method.

Set_output ($output);//
Set $this->final_output
Allows you to manually set the final output string. Examples of Use:
$this->output->set_output ($data);

Append_output ($output)
Append data to the output string.
$this->output->append_output ($data);

Third, header function cluster
Get_header ()
Returns the HTTP header of the request, or NULL if the HTTP header is not set. For example:
$this->output->set_content_type (' Text/plain ', ' UTF-8 ');
echo $this->output->get_header (' Content-type ');
Outputs:text/plain; Charset=utf-8

Set_header ($header, $replace = TRUE)
Allows you to manually set the HTTP header of the server, and the output class will send it when the page is finally displayed. For example:
$this->output->set_header (' http/1.1 OK ');
$this->output->set_header (' last-modified: '. Gmdate (' d, D M Y h:i:s ', $last _update). ' GMT ');
$this->output->set_header (' Cache-control:no-store, No-cache, Must-revalidate ');
$this->output->set_header (' cache-control:post-check=0, pre-check=0 ');
$this->output->set_header (' Pragma:no-cache ');

If PHP has zlib.output_compression compression turned on, skip the content-length header settings
The reason for this is that when the compression is turned on, the actual output byte count is less than normal, and after the Content-length header is set incorrectly, it causes the client to wait until the server sends enough bytes of text, resulting in an inability to respond properly.
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;
}

Four, Content_Type function cluster:
Information like this is included in the header information for each server response: Content-type: "text/html; Charset=utf-8 "
The source file has meta information <meta http-equiv= "Content-type" content= "text/html; Charset=utf-8 ">
When the server outputs to the client, it tells the client what type of data I'm going to give you, and the client browser parses the message in a corresponding way.
For example, now that the server is going to export a set of Excel tabular data to the client, you can use content= "Application/excel" to tell the client that this is an Excel file that you should treat in the same way as Excel. Some plug-in browser may be opened in itself to display, and some are prompted to download the Excel type of files. Then Application/excel is called MIME information.
The correspondence between MIME information and different files is available in application/config/mimes.php.

Add content_type information to head
1, Set_content_type ($mime _type, $charset = NULL)
Allows you to set the MIME type of your page, it is convenient to provide JSON data, JPEG, XML and other formats.
$this->output
->set_content_type (' Application/json ')
->set_output (Json_encode (Array (' foo ' = ' bar '));

$mime _type is the file name extension to set MIME information, the system finds the MIME information in the corresponding extension from the $mimes array
if (Strpos ($mime _type, '/') = = = = FALSE)
{
$extension = LTrim ($mime _type, '. ');

Is this extension supported?
if (Isset ($this->mimes[$extension]))
{
$mime _type =& $this->mimes[$extension];

if (Is_array ($mime _type))
{
$mime _type = current ($mime _type);
}
}
}
Here the program uses the IF (Strpos ($mime _type, '/') = = = FALSE), indicating that if the argument is an extension (pptx,jpeg), the $mimes array is matched.
If the parameter includes "/", the system thinks that the method parameter type value is MIME information, such as Application/octet-stream, then directly $this->mime_type = $mime _type;
Next set the CharSet information, if the parameters are not set, the charset settings of the enrolled profile.

2, Get_content_type ()
Gets the HTTP header Content-type currently in use, not including the character set section.
$mime = $this->output->get_content_type ();
The system matches the Content-type information from a bunch of header information, finds the MIME value that is returned, and returns the default text/html if it is not found.
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 ';
}

Five, Profiler function cluster
Public Function Enable_profiler ($val = TRUE);//Set $enable_profiler value whether the parser is turned on
Public Function set_profiler_sections ($sections);//Set the contents of the parser
Allows you to enable or disable the Program Analyzer, which displays the results of the benchmark test or some other data at the bottom of your page to help you debug and optimize your program.
$this->output->enable_profiler (TRUE);

Vi. Write Cache: _write_cache ($output)
The main process is to generate a MD5 as the access cache key based on the URI information accessed, and then write the content to the file.
1, instance $ci controller to like $ci =& get_instance ();
2. Get the cache path:
The Cache path $ci->config->item (' Cache_path ') is obtained through the configuration file, and if not set, the Application/cache path is used by default
If the path does not exist or is not writable, the error log is logged and returned.
3. Generate the Cache key:
Get $cachpath: Generates a unique string based on a URI, which can be considered a cached key.
A. Get the current address, the. In particular, the URI class is used here, and the opening is detailed.
B.1 If the cache_query_string value is set in the configuration file (that is, the variable that is allowed to be cached in the QueryString), the intersection of the array set in the _get array with the cache_query_string is taken.
Give a chestnut:
$config [' cache_query_string '] = Array (' CID ', ' page ');
So if the current URL is: Http://mysite/balabala?cid=1&page=2&sort=viewnumber&sorttype=desc
So eventually uri.=http://mysite/balabala?cid=1&page=2
B.2 If the cache_query_string value is not set, then uri.=$_server[' query_string '; will load the entire address in.

C, the URI with the MD5 () function to generate a unique string, can be considered as a cache key, the final path of the cache file $cache_path.

4. Create a handle to the cache file:
Open the $cache_path file to get the handle $fp

------>>>>>> make a row for the file lock flock ($FP, LOCK_EX);

5, compression processing:
If Zlib.output_compression is not turned on in the php.ini, and compression is required in the configuration file, it is compressed using Gzencode in the program (this is done in the constructor)
$output = Gzencode ($output)
After compression is complete, set the Content-type

6. Expiration Time $expire Set

7, generate the final output $output.
The $output is divided into three segments:
1. Expire,headers serialized into a string
2. Delimiter: ENDCI--->
3, pre-output $output content.

8. Write to file.
When writing to a network file stream, there is a case where the characters are not written completely to the file, which is especially common in large files. You need to use the Fwrite return value: The number of characters written to detect exactly how many characters are written, and if the number of characters is insufficient, you can repeat the fwrite.
The document says: Writing to a network stream may end before the whole string is written. Return value of fwrite () may checked:

------>>>>>> Unlock Flock ($fp, LOCK_EX);


VII. Display cache: Public function _display_cache (& $CFG, & $URI)
Read cache text, determine expiration no, call _display output
1. Get the cache path from the configuration

2. Get the cache key based on the URI and piece together the cache path $filepath
$filepath = $cache _path.md5 ($uri);
3, read the file to the variable $cache. If there is no cache, return false, the external CI workflow will continue to execute
if (! file_exists ($filepath) OR! $fp = @fopen ($filepath, ' RB '))
{
return FALSE;
}
4, get $cache_info, that is, the previous write cache in the ENDCI---> Front plus expire,headers information
6. Determine cache Expiration Time
if ($_server[' request_time ' >= $expire && is_really_writable ($cache _path))
{
If so we ' ll delete it.
@unlink ($filepath);
Log_message (' Debug ', ' Cache file ' has expired. File deleted. ');
return FALSE;
}
Else
{
Or else send the HTTP cache control headers.
$this->set_cache_header ($last _modified, $expire);
}
A. If it expires, delete the original cache file and return false; The external CI workflow will continue to execute downwards.
B. If there is no expiration, call Set_cache_header ($last _modified, $expiration)
B.1 If the http_if_modified_since header is set and the last modification time of the file does not exceed Http_if_modified_since time, the 304 status code is sent directly to the client, allowing the client to invoke the local cache, about HTTP_IF_ Modified_since and 304 states, you can refer to the "HTTP authoritative guide" book.
B.2 If the file modification time exceeds the http_if_modified_since time, the header information is resent, telling the client to cache the result of the request locally.
if (Isset ($_server[' http_if_modified_since ')) && $last _modified <= strtotime ($_server[' http_if_modified_ SINCE ']))
{
$this->set_status_header (304);
Exit
}
Else
{
Header (' Pragma:public ');
Header (' cache-control:max-age= '. $max _age. ', public ');
Header (' Expires: '. Gmdate (' d, D M Y h:i:s ', $expiration). ' GMT ');
Header (' last-modified: '. Gmdate (' d, D M Y h:i:s ', $last _modified). ' GMT ');
}
7. Set header information according to expire in cache
foreach ($cache _info[' headers ') as $header)
{
$this->set_header ($header [0], $header [1]);
}
8. Call the content portion of the _display output $cache
$this->_display (substr ($cache, strlen ($match [0]));

Viii. _display ($output = ")
Sends the final output as well as the server's HTTP header to the browser, and it also stops the benchmark timer.
1. Loading and instantiating the Benchmark,config class
$BM =& load_class (' Benchmark ', ' core ');
$CFG =& load_class (' Config ', ' core ')
Use Load_class () instead of using an instance of the $ci =& Get_instance () controller to load the class library because the method is sometimes called by the cache mechanism, which is said above
_display_cache () function call, when the context of the current request does not load the controller class at all, so the controller cannot be instantiated correctly


2, instantiate Ci_controller, if is the cache, that will not real image. This is important, and the next step is to Isset ($CI) to see if it's a cache. Cache is distinct from non-cached processing
if (class_exists (' Ci_controller ', FALSE))
{
$CI =& get_instance ();
}

3, write cache (response to the cache (n) method): Determine the $cache_expiration property, this value can be set by the method cache (n), and then determine whether the controller is used to _output () expansion of its own output, if not, write cache
if ($this->cache_expiration > 0 && isset ($CI) && method_exists ($CI, ' _output '))
{
$this->_write_cache ($output);
}

4. Resolve replacement Pseudo-variable {elapsed_time}, {memory_usage}
$memory = Round (Memory_get_usage ()/1024/1024, 2). ' MB ';
$output = str_replace (Array (' {elapsed_time} ', ' {memory_usage} '), Array ($elapsed, $memory), $output);

5, determine whether to execute the PHP code-side compression, if the cache is skipped (because it has been compressed), if it is a normal controller and _compress_output is true, and the client browser tells the server to support the compression format of gzip, do Ob_start (' Ob_ Gzhandler ');
Isset ($CI) indicates that this paragraph does not take effect on the cache.
if (Isset ($CI) && $this->_compress_output = = = TRUE && isset ($_server[' http_accept_encoding ')) & & Strpos ($_server[' http_accept_encoding ', ' gzip ')!== FALSE) {
Ob_start (' Ob_gzhandler ');
}
6. Output header information
if (count ($this->headers) > 0)
{
foreach ($this->headers as $header)
{
@header ($header [0], $header [1]);
}
}
7, if! Isset ($CI), which represents the cache. Then according to the client $_server[' http_accept_encoding ' information, determine whether to output compressed content, or output the original extracted content.
In the case of caching, the entire CI process is completed after the output.
if ($this->_compress_output = = = TRUE)
{
If the client supports compression
if (Isset ($_server[' http_accept_encoding ')) && strpos ($_server[' http_accept_encoding '], ' gzip ')!== FALSE)
{
Header (' Content-encoding:gzip ');
Header (' Content-length: '. strlen ($output));
}
Else
{
If compression is not supported, unzip the cache file to output. SUBSTR ($output, 10,-8) A lot of people don't understand why they're dealing with it.
PHP 5.4 After the addition of the Gzip decompression function Gzdecode. Many of the space service providers have not reached the PHP version of 5.4, which also led to the use of this function after the function undefined error, the PHP official website user submitted the log that someone gave a good solution, using Gzin The Flate function is substituted, but the data is processed.
$output = Gzinflate (substr ($output, 10,-8));
}
}
Echo $output;

8. Generate analysis Data ($this->enable_profiler) Add HTML to $output, and the profiler class library starts with another
9. Call the custom method in the controller _output the final result is processed last. Of course, we can not deal with it.



Learn PHP Advanced development skills from CI source--codeigniter Framework Source Depth Analysis (4): Output class output.php

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.