我在一个简单的缓存系统中工作,该系统由php生成,并由apache .htaccess
响应(在实际服务器中由nginx响应)。
PHP使用public/cache/post/35/my-first-post.html
等文件将缓存文件创建到public/cache/
中
VirtualHost对所有项目来说都是通用的,在开发过程中,我们没有为每个项目提供VirtualHost:
<VirtualHost *:80>
DocumentRoot /var/www
<Directory /var/www>
Options -Indexes
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
位于/var/www/projects/current-project/public/.htaccess
中的.htaccess
应该检测到该缓存文件并将其返回。
DirectoryIndex index.php
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond cache/$1.html -f
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Url为http://localhost/projects/current-project/public/post/35/my-first-post但是生产服务器http://domain.com/post/35/my-first-post
并重写日志:
[Sun May 08 13:55:11.236124 2016] [rewrite:trace4] [pid 3189] mod_rewrite.c(476): [client 127.0.0.1:43494] 127.0.0.1 - - [localhost/sid#7f2d26745ae0][rid#7f2d2668e0a0/initial] [perdir /var/www/projects/current-project/public/] RewriteCond: input='cache/post/1/my-first-post.html' pattern='-f' => not-matched
文件perdir /var/www/projects/current-project/public/
+input='cache/post/1/my-first-post.html'
=/var/www/projects/current-project/public/cache/post/1/my-first-post.html
存在。
我不想设置RewriteBase
,因为它对每个开发环境都是动态的。
如何从当前.htaccess
文件夹中检测缓存文件?
工作nginx版本:
set $cachefile "";
if ($uri ~ ^[a-z0-9/-]+$) {
set $cachefile "/cache/$uri.html";
}
if ($uri = "/") {
set $cachefile "/cache/index.html";
}
location / {
try_files $cachefile $uri $uri/ /index.php?$query_string;
}
工作解决方案感谢@Sumurai8:
DirectoryIndex index.php
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# No request: index cache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1#%{REQUEST_FILENAME} ^/?#(.*/public)/
RewriteCond %1/cache/index.html -f
RewriteRule ^$ cache/index.html [L,NC]
# Request: page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1#%{REQUEST_FILENAME} ^([a-z0-9/-]+)#(.*/public)/
RewriteCond %2/cache/%1.html -f
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L,NC]
# Catch all script and cache generator
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
谢谢。
-f
和其他类似的检查适用于文件名,而不是URL。您应该首先在%{REQUEST_FILENAME}
上进行匹配,然后构造自己的文件名。
RewriteCond $1#%{REQUEST_FILENAME} ^([a-z0-9/-]+)#(.*/public)/
RewriteCond %2/cache/%1.html -f
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]
($1
是规则的第一个捕获组,它包含缓存文件的后一部分。在第二个条件中,%2
是前一个条件的第二个捕获组。它包含文档根+当前前缀。)
或者,您可以盲目地重写缓存,如果缓存不存在,则再次重写:
RewriteCond %{REQUEST_URI} !^/cache/
RewriteRule ^([a-z0-9/-]+)$ cache/$1.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
在您的情况下,index.php
需要识别缓存url,这可能会很麻烦。