[英]How to cache dynamic PHP page
如何緩存具有mysql查詢的PHP頁面。 任何一個例子都會很有幫助。
我正在使用phpFastCache (用於共享主機,如果你不想觸摸php.ini和root來設置memcached)。 查看示例菜單。 他們有完整的詳細示例,非常簡單。
首先你用phpFastCache :: set設置然后用phpFastCache :: get - DONE獲取!
示例:減少數據庫調用
您的網站有10,000名在線訪問者,您的動態頁面必須在每次加載頁面時向數據庫發送10,000個相同的查詢。 使用phpFastCache,您的頁面只向DB發送1個查詢,並使用緩存為9,999個其他訪問者提供服務。
<?php
// In your config file
include("php_fast_cache.php");
phpFastCache::$storage = "auto";
// you can set it to files, apc, memcache, memcached, pdo, or wincache
// I like auto
// In your Class, Functions, PHP Pages
// try to get from Cache first.
$products = phpFastCache::get("products_page");
if($products == null) {
$products = YOUR DB QUERIES || GET_PRODUCTS_FUNCTION;
// set products in to cache in 600 seconds = 5 minutes
phpFastCache::set("products_page",$products,600);
}
OUTPUT or RETURN your $products
?>
我的偏好是使用緩存反向代理,如Varnish 。
就純PHP解決方案而言,您可以在腳本末尾放置一些緩存最終輸出的代碼,並在開頭檢查以查看頁面是否緩存。 如果在緩存中找到該頁面,則發送它並退出而不是再次運行查詢。
<?php
function cache_file() {
// something to (hopefully) uniquely identify the resource
$cache_key = md5($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']);
$cache_dir = '/tmp/phpcache';
return $cache_dir . '/' . $cache_key;
}
// if we have a cache file, deliver it
if( is_file( $cache_file = cache_file() ) ) {
readfile( $cache_file );
exit;
}
// cache via output buffering, with callback
ob_start( 'cache_output' );
//
// expensive processing happens here, along with page output.
//
function cache_output( $content ) {
file_put_contents( cache_file(), $content );
return $content;
}
顯然,這需要對您的設置進行大量自定義,包括緩存過期,滿足您需求的$cache_key
以及錯誤檢測,以便不緩存錯誤的頁面。
<?php
//settings
$cache_ext = '.html'; //file extension
$cache_time = 3600; //Cache file expires afere these seconds (1 hour = 3600 sec)
$cache_folder = 'cache/'; //folder to store Cache files
$ignore_pages = array('', '');
$dynamic_url = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url)
$cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file
$ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list
if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired.
ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip.
readfile($cache_file); //read Cache file
echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->';
ob_end_flush(); //Flush and turn off output buffering
exit(); //no need to proceed further, exit the flow.
}
//Turn on output buffering with gzip compression.
ob_start('ob_gzhandler');
######## Your Website Content Starts Below #########
?>
<!DOCTYPE html>
<html>
<head>
<title>Page to Cache</title>
</head>
<body>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ut tellus libero.
</body>
</html>
<?php
######## Your Website Content Ends here #########
if (!is_dir($cache_folder)) { //create a new folder if we need to
mkdir($cache_folder);
}
if(!$ignore){
$fp = fopen($cache_file, 'w'); //open file for writing
fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file
fclose($fp); //Close file pointer
}
ob_end_flush(); //Flush and turn off output buffering
?>
memcache你的html然后做這樣的事情:
$memcache = memcache_connect('localhost', 11211);
$page = $memcache->get('homepage');
if($page == ""){
$mtime = microtime();
$page = get_home();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
memcache_set($memcache, 'homepage', $page, 0, 30);
$page .= "\n<!-- Duly stored ($totaltime) -->";
}
else{
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
$page .= "\n<!-- served from memcache ($totaltime) -->";
}
die($page);
在討論緩存時經常忽略的重要事情是進程同步以避免線程競爭(請參閱: https : //en.wikipedia.org/wiki/Race_condition )。
PHP中沒有同步的典型緩存方案如下所示:如果緩存中沒有資源,或者資源已過期,則必須創建它並將其放入緩存中。 碰巧遇到這種情況的第一個線程/進程正在嘗試創建資源,在此期間,其他線程也將創建資源,這會導致線程爭用,緩存砰擊和性能下降。
問題由資源創建任務創建的並發線程數和工作負載數放大。 在繁忙的系統上,它可能會導致嚴重的問題。
PHP的緩存系統很少考慮同步。
其中一個是php-no-slam-cache: https : //github.com/tztztztz/php-no-slam-cache
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.