[ Index ] |
|
Code source de LifeType 1.2.4 |
1 <?php 2 3 //In RSS/ATOM feedMode, contains the date of the clients last update. 4 $clientCacheDate=0; //Global public variable because PHP4 does not allow conditional arguments by reference 5 $_sessionMode=false; //Global private variable 6 7 /** 8 * \ingroup Net_HTTP 9 * Enable support for HTTP/1.x conditional requests in PHP. 10 * Goal: Optimisation 11 * - If the client sends a HEAD request, avoid transferring data and return the correct headers. 12 * - If the client already has the same version in its cache, avoid transferring data again (304 Not Modified). 13 * - Possibility to control cache for client and proxies (public or private policy, life time). 14 * - When $feedMode is set to true, in the case of a RSS/ATOM feed, 15 * it puts a timestamp in the global variable $clientCacheDate to allow the sending of only the articles newer than the client's cache. 16 * - When $compression is set to true, compress the data before sending it to the client and persitent connections are allowed. 17 * - When $session is set to true, automatically checks if $_SESSION has been modified during the last generation the document. 18 * 19 * Interface: 20 * - function httpConditional($UnixTimeStamp,$cacheSeconds=0,$cachePrivacy=0,$feedMode=false,$compression=false) 21 * [Required] $UnixTimeStamp: Date of the last modification of the data to send to the client (Unix Timestamp format). 22 * [Implied] $cacheSeconds=0: Lifetime in seconds of the document. If $cacheSeconds>0, the document will be cashed and not revalidated against the server for this delay. 23 * [Implied] $cachePrivacy=0: 0=private, 1=normal (public), 2=forced public. When public, it allows a cashed document ($cacheSeconds>0) to be shared by several users. 24 * [Implied] $feedMode=false: Special RSS/ATOM feeds. When true, it sets $cachePrivacy to 0 (private), does not use the modification time of the script itself, and puts the date of the client's cache (or a old date from 1980) in the global variable $clientCacheDate. 25 * [implied] $compression=false: Enable the compression and allows persistant connections (automatic detection of the capacities of the client). 26 * [implied] $session=false: To be turned on when sessions are used. Checks if the data contained in $_SESSION has been modified during the last generation the document. 27 * Returns: True if the connection can be closed (e.g.: the client has already the lastest version), false if the new content has to be send to the client. 28 * 29 * Typical use: 30 * <?php 31 * require_once('http-conditional.php'); 32 * //Date of the last modification of the content (Unix Timestamp format). 33 * //Examples: query the database, or last modification of a static file. 34 * $dateLastModification=...; 35 * if (httpConditional($dateLastModification)) 36 * { 37 * ... //Close database connections, and other cleaning. 38 * exit(); //No need to send anything 39 * } 40 * //Do not send any text to the client before this line. 41 * ... //Rest of the script, just as you would do normally. 42 * ?> 43 * 44 * Version 1.6.1, 2005-04-03, http://alexandre.alapetite.net/doc-alex/php-http-304/ 45 * 46 * ------------------------------------------------------------------ 47 * Written by Alexandre Alapetite, http://alexandre.alapetite.net/cv/ 48 * 49 * Copyright 2004-2005, Licence: Creative Commons "Attribution-ShareAlike 2.0 France" BY-SA (FR), 50 * http://creativecommons.org/licenses/by-sa/2.0/fr/ 51 * http://alexandre.alapetite.net/divers/apropos/#by-sa 52 * - Attribution. You must give the original author credit 53 * - Share Alike. If you alter, transform, or build upon this work, 54 * you may distribute the resulting work only under a license identical to this one 55 * - The French law is authoritative 56 * - Any of these conditions can be waived if you get permission from Alexandre Alapetite 57 * - Please send to Alexandre Alapetite the modifications you make, 58 * in order to improve this file for the benefit of everybody 59 * 60 * If you want to distribute this code, please do it as a link to: 61 * http://alexandre.alapetite.net/doc-alex/php-http-304/ 62 */ 63 class HttpCache { 64 function httpConditional($UnixTimeStamp,$cacheSeconds=0, 65 $cachePrivacy=0,$feedMode=false, 66 $compression=false,$session=false){ 67 //Credits: http://alexandre.alapetite.net/doc-alex/php-http-304/ 68 //RFC2616 HTTP/1.1: http://www.w3.org/Protocols/rfc2616/rfc2616.html 69 //RFC1945 HTTP/1.0: http://www.w3.org/Protocols/rfc1945/rfc1945.txt 70 71 if (headers_sent()) return false; 72 73 if (isset($_SERVER['SCRIPT_FILENAME'])) $scriptName=$_SERVER['SCRIPT_FILENAME']; 74 elseif (isset($_SERVER['PATH_TRANSLATED'])) $scriptName=$_SERVER['PATH_TRANSLATED']; 75 else return false; 76 77 if ((!$feedMode)&&(($modifScript=filemtime($scriptName))>$UnixTimeStamp)) 78 $UnixTimeStamp=$modifScript; 79 $UnixTimeStamp=min($UnixTimeStamp,time()); 80 $is304=true; 81 $is412=false; 82 $nbCond=0; 83 84 //rfc2616-sec3.html#sec3.3.1 85 $dateLastModif=gmdate('D, d M Y H:i:s \G\M\T',$UnixTimeStamp); 86 $dateCacheClient='Thu, 10 Jan 1980 20:30:40 GMT'; 87 88 //rfc2616-sec14.html#sec14.19 //='"0123456789abcdef0123456789abcdef"' 89 if (isset($_SERVER['QUERY_STRING'])) $myQuery='?'.$_SERVER['QUERY_STRING']; 90 else $myQuery=''; 91 if ($session&&isset($_SESSION)) 92 { 93 global $_sessionMode; 94 $_sessionMode=$session; 95 $myQuery.=print_r($_SESSION,true).session_name().'='.session_id(); 96 } 97 $etagServer='"'.md5($scriptName.$myQuery.'#'.$dateLastModif).'"'; 98 99 if ((!$is412)&&isset($_SERVER['HTTP_IF_MATCH'])) 100 {//rfc2616-sec14.html#sec14.24 101 $etagsClient=stripslashes($_SERVER['HTTP_IF_MATCH']); 102 $is412=(($etagClient!='*')&&(strpos($etagsClient,$etagServer)===false)); 103 } 104 if ($is304&&isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) 105 {//rfc2616-sec14.html#sec14.25 //rfc1945.txt 106 $nbCond++; 107 $dateCacheClient=$_SERVER['HTTP_IF_MODIFIED_SINCE']; 108 $p=strpos($dateCacheClient,';'); 109 if ($p!==false) 110 $dateCacheClient=substr($dateCacheClient,0,$p); 111 $is304=($dateCacheClient==$dateLastModif); 112 } 113 if ($is304&&isset($_SERVER['HTTP_IF_NONE_MATCH'])) 114 {//rfc2616-sec14.html#sec14.26 115 $nbCond++; 116 $etagClient=stripslashes($_SERVER['HTTP_IF_NONE_MATCH']); 117 $is304=(($etagClient==$etagServer)||($etagClient=='*')); 118 } 119 if ((!$is412)&&isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE'])) 120 {//rfc2616-sec14.html#sec14.28 121 $dateCacheClient=$_SERVER['HTTP_IF_UNMODIFIED_SINCE']; 122 $p=strpos($dateCacheClient,';'); 123 if ($p!==false) 124 $dateCacheClient=substr($dateCacheClient,0,$p); 125 $is412=($dateCacheClient!=$dateLastModif); 126 } 127 if ($feedMode) 128 {//Special RSS/ATOM 129 global $clientCacheDate; 130 $clientCacheDate=strtotime($dateCacheClient); 131 $cachePrivacy=0; 132 } 133 134 if ($is412) 135 {//rfc2616-sec10.html#sec10.4.13 136 header('HTTP/1.1 412 Precondition Failed'); 137 header('Cache-Control: private, max-age=0, must-revalidate'); 138 header('Content-Type: text/plain'); 139 echo "HTTP/1.1 Error 412 Precondition Failed: Precondition request failed positive evaluation\n"; 140 return true; 141 } 142 elseif ($is304&&($nbCond>0)) 143 {//rfc2616-sec10.html#sec10.3.5 144 header('HTTP/1.0 304 Not Modified'); 145 header('Etag: '.$etagServer); 146 if ($feedMode) header('Connection: close'); //Comment this line under IIS 147 return true; 148 } 149 else 150 {//rfc2616-sec10.html#sec10.2.1 151 //rfc2616-sec14.html#sec14.3 152 if ($compression) ob_start('_httpConditionalCallBack'); //Will check HTTP_ACCEPT_ENCODING 153 //header('HTTP/1.0 200 OK'); 154 if ($cacheSeconds==0) 155 { 156 $cache='private, must-revalidate, '; 157 //$cacheSeconds=-1500000; //HTTP/1.0 158 } 159 elseif ($cachePrivacy==0) $cache='private, '; 160 elseif ($cachePrivacy==2) $cache='public, '; 161 else $cache=''; 162 $cache.='max-age='.floor($cacheSeconds); 163 // header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T',time()+$cacheSeconds)); //HTTP/1.0 //rfc2616-sec14.html#sec14.21 164 header('Cache-Control: '.$cache); //rfc2616-sec14.html#sec14.9 165 header('Last-Modified: '.$dateLastModif); 166 header('Etag: '.$etagServer); 167 if ($feedMode) header('Connection: close'); //rfc2616-sec14.html#sec14.10 //Comment this line under IIS 168 return $_SERVER['REQUEST_METHOD']=='HEAD'; //rfc2616-sec9.html#sec9.4 169 } 170 } 171 172 function _httpConditionalCallBack($buffer,$mode=5){ 173 //Private function automatically called at the end of the script when compression is enabled 174 //rfc2616-sec14.html#sec14.11 175 //You can adjust the level of compression with zlib.output_compression_level in php.ini 176 if (extension_loaded('zlib')&&(!ini_get('zlib.output_compression'))) 177 { 178 $buffer2=ob_gzhandler($buffer,$mode); //Will check HTTP_ACCEPT_ENCODING and put correct headers 179 if (strlen($buffer2)>1) //When ob_gzhandler succeeded 180 $buffer=$buffer2; 181 } 182 header('Content-Length: '.strlen($buffer)); //Allows persistant connections //rfc2616-sec14.html#sec14.13 183 return $buffer; 184 } 185 186 function httpConditionalRefresh($UnixTimeStamp){ 187 //Update HTTP headers if the content has just been modified by the client's request 188 //See an example on http://alexandre.alapetite.net/doc-alex/compteur/ 189 if (headers_sent()) return false; 190 191 if (isset($_SERVER['SCRIPT_FILENAME'])) $scriptName=$_SERVER['SCRIPT_FILENAME']; 192 elseif (isset($_SERVER['PATH_TRANSLATED'])) $scriptName=$_SERVER['PATH_TRANSLATED']; 193 else return false; 194 195 $dateLastModif=gmdate('D, d M Y H:i:s \G\M\T',$UnixTimeStamp); 196 197 if (isset($_SERVER['QUERY_STRING'])) $myQuery='?'.$_SERVER['QUERY_STRING']; 198 else $myQuery=''; 199 global $_sessionMode; 200 if ($_sessionMode&&isset($_SESSION)) 201 $myQuery.=print_r($_SESSION,true).session_name().'='.session_id(); 202 $etagServer='"'.md5($scriptName.$myQuery.'#'.$dateLastModif).'"'; 203 204 header('Last-Modified: '.$dateLastModif); 205 header('Etag: '.$etagServer); 206 } 207 } 208 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 21:04:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |