我有一个Php网站,它已经为一些页面创建了一个完整的输出缓存文件,虽然没有保存为.html
,并且在请求上仍然从Php发送,它错过了静态文件的托管缓存,具有非常好的性能。
缓存文件根据其md5(Url)
保存在一个目录中。
我想知道是否与mod_rewrite
将有可能获得类似的结果,但与html静态文件,我想我已经看到了类似的东西前一段时间与WordPress缓存插件(但在当时我没有太注意)。
我可以用什么代替md5()
与mod_rewrite
转换整个Url在一个有效的唯一的文件名?
我的Url是虚拟路由,非常简单:/level1/level2/level3/
(是一个仍在进行中的工作,但我不认为使用超过3个级别,levelN
显然是一个例子,可以是任何单词)
我想简化一下:
mod_rewrite:/cache/unique(Url).html exist?加载它
php:/cache/unique(Url).html不存在?
创建它我可以为unique
使用什么?
是的,你可以这样做,我不打算提供整个代码,只是想法就足够了。
从.htaccess
开始编写.htaccess的方式是将每个丢失的文件重定向到目录索引。它可以是这样的
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
现在你将得到请求到index.php如果被调用的页面是没有找到。
与其使用散列文件名,不如使用目录结构,这样会更快,更容易读懂。
您可以动态地创建目录。
在<<p> strong> index . php在将数据推回浏览器之前,请确保所有数据都保存在一个变量中。您可以使用include函数来做到这一点。参见本页例5。
根据目录级别保存数据。
$levels = explode('/',<REQUESTED_URI>);
$filename = array_pop($levels);
foreach($levels as $level)
// Create Directory if does not exit
最后,这只是基本的想法,你必须自己找出技巧和技巧。
最后很简单,虽然我必须使用相同的目录和Url的子目录,但我记得的WordPress插件是超级缓存,我使用的mod_rewrite
几乎是相同的。
使用.htaccess
和mod_rewrite
转换Url是可能的,但并不简单,并且有一些限制(但即使是md5使用RewriteMap
和prg
,如果您有权访问服务器配置)。
.htaccess
如果静态缓存文件存在,加载它:
RewriteCond %{DOCUMENT_ROOT}/cache/$1/index.html -f
RewriteRule ^(.*) /cache/$1/index.html [L]
Php,我使用CodeIgniter,但应该很容易编辑Php,也许使用ob_start
和ob_get_clean
:
private function cache_output() {
$this->load->helper('url');
$uri = uri_string(); /* expect something like: level1/level2 (no heading/trailing slash */
$dir = FCPATH.'cache'.DIRECTORY_SEPARATOR.str_replace('/',DIRECTORY_SEPARATOR,$uri);
$file = $dir.DIRECTORY_SEPARATOR.'index.html';
if (!file_exists($file)) {
if (!is_dir($dir)) {
mkdir($dir, 0755 & ~umask(), TRUE);
}
$output = $this->output->get_output();
file_put_contents($file, $output);
chmod($file, 0644 & ~umask());
}
}
我几年前使用过类似的东西,并设法找到了源代码。我的.htaccess
设置看起来像这样:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}/cache/index.html -f
RewriteRule ^$ /cache/index.html [QSA,L]
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{DOCUMENT_ROOT}/cache/$1.html -f
RewriteRule ^(.*[^/])/?$ /cache/$1.html [L]
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)?$ ./index.php [L]
它支持通过不同的文件名获取起始页,并且在任何post请求时跳过缓存。
生成该文件的PHP代码非常简单:ob_start();
// ... main page code & output
$url = $_SERVER['REQUEST_URI'];
$html = ob_get_clean();
$start = array('/', '', '/index.php');
$blacklisted = array('/some/url/exception', 'another/one');
if (in_array($url, $start, true)) {
$path = './cache/';
$file = 'index.html';
} else {
$pos = strpos(strrev($url), '/');
$pos = ($pos ? (strlen($url) - ($pos - 1)) : false);
$path = './cache' . substr($url, 0, $pos, '/'));
$file = substr(strrchr(rtrim($url, '/'), '/'), 1) . '.html';
}
if (!in_array($url, $blacklisted, true)) {
$parts = explode('/', $path);
foreach($parts as $part) {
$dir = (isset($dir) ? $dir . $part . '/' : $part . '/' );
if (!file_exists($dir)) {
@mkdir($dir, 0777);
}
}
file_put_contents($path . '/' . $file, $html);
}
对于缓存无效,我在POST请求时手动调用@unlink('./cache/comment/id/'. $id . '.html');
来编辑内容。有时glob()
类型的递归删除嵌套的资源url。
对于页面的动态部分,比如客人和登录用户的不同的菜单,我只是使用了一些Javascript和cookie来确定要显示的内容。