RewriteRule用于在子目录中存储数千个文件

时间:2010-04-30 21:51:03

标签: apache mod-rewrite

我的网站在目录中有数百万个页面。我想根据页面名称的第一个字符将这些文件存储在一堆子目录中。

例如 http://mysite.com/hugedir/somefile.html

将存储在/var/www/html/hugedir/s/o/m/e/f/ile.html

对于像这样的RewriteRule来说,这是微不足道的:

RewriteRule ^hugedir/(.)(.)(.)(.)(.)(.*).html   /hugedir/{$1}/{$2}/{$3}/{$4}/{$5}/$6.html
RewriteRule ^hugedir/(.)(.)(.)(.)(.*).html      /hugedir/{$1}/{$2}/{$3}/{$4}/{$5}.html
RewriteRule ^hugedir/(.)(.)(.)(.*).html         /hugedir/{$1}/{$2}/{$3}/{$4}.html
RewriteRule ^hugedir/(.)(.)(.*).html            /hugedir/{$1}/{$2}/{$3}.html
RewriteRule ^hugedir/(.)(.*).html               /hugedir/{$1}/{$2}.html
RewriteRule ^hugedir/(.*).html                  /hugedir/{$1}.html

但是,文件名可能包含连字符或其他非标准字符,而我确实喜欢避免使用以奇怪字符命名的目录。理想情况下,我想要一个“已批准”字符列表,并将未批准的字符排除或转换为下划线。

有人可以想办法吗?还是别的东西?部分要求是这些是磁盘上的物理文件,而不是使用脚本语言进行解析。

2 个答案:

答案 0 :(得分:0)

Apache mod_rewrite允许您指定外部程序来进行映射。 (搜索“外部重写程序”)。例如,你可以在Perl中完成它。

例如:

#!/usr/bin/perl
$| = 1;
while (<STDIN>) {
     chomp;
     $dir= $_ . "_________";
     $file = $_;
     $dir =~ tr/a-zA-Z0-9/X/c;
     $dir =~ s!^(.)(.)(.)(.).*!$1/$2/$3/$4!;
     print "$dir/$file\n";
}

答案 1 :(得分:0)

通过将字符转换为下划线,您将遇到碰撞问题。例如,--a-=a都会转换为_/_/a

处理问题的更好方法是使用RewriteMap和内置escape函数转义字符:

RewriteMap escape int:escape
RewriteRule hugedir/(.*).html /hugedir/${escape:1}.html
RewriteRule hugedir/(.)(.*).html /hugedir/${escape:1}/${escape:2}.html