从.htaccess

时间:2016-05-08 12:14:55

标签: php apache .htaccess mod-rewrite caching

我在php生成的简单缓存系统中工作,并从apache .htaccess(在nginx的真实服务器中)做出响应。

PHP使用public/cache/

等文件将缓存文件创建到public/cache/post/35/my-first-post.html

VirtualHost对于所有项目都是通用的,在开发中我们没有为每个项目提供VirtualHost:

<VirtualHost *:80>
    DocumentRoot /var/www

    <Directory /var/www>
        Options -Indexes
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
位于.htaccess

/var/www/projects/current-project/public/.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>

网址为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>

感谢。

1 个答案:

答案 0 :(得分:2)

-f和其他类似检查适用于文件名,而不是网址。您应首先匹配%{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需要识别缓存网址,这可能很麻烦。