【问题标题】:mod_rewrite prefix problemmod_rewrite 前缀问题
【发布时间】:2010-08-09 02:55:26
【问题描述】:

我在使用 mod_rewrite 时遇到了一些困难。我的目录结构(部分)是:

index.php
.htaccess
app
  controllers
  models
  views
  ...
  public
    javascripts
    stylesheets
    foo
      bar

所以,如您所见,所有静态文件都在 app/public 中。这就是我想路由请求的原因:

http://www.example.com/images/logo.png => app/public/images/logo.png  
http://www.example.com/javascripts/app.js => app/public/javascripts/app.js  
http://www.example.com/uploads/blog/something => app/public/uploads/blog/something

如果该文件不存在,那么它应该路由到 index.php,例如:

http://www.example.com/news/show/42 => index.php 
(Because file app/public/news doens't exist)


所以,这是我当前的 .htaccess,但我认为它可以以更优雅的方式完成。

RewriteEngine on
RewriteRule (png|jpg|gif|bmp|ico)$ app/public/images/$1/$2.$3 [L]
RewriteRule ([^/.]+).js$ app/public/javascripts/$1.js [L]
RewriteRule ([^/.]+).css$ app/public/stylesheets/$1.css [L]
RewriteRule ^(.*)$   index.php    [NC,L,QSA]

另外,这个问题是,它只处理图像、javascripts 和样式表,而不是所有其他文件。

我知道有:

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d

但是,我不知道如何使用前缀“app/public/”路由它们?我试过了:

RewriteCond app/public/%{SCRIPT_FILENAME} !-f
RewriteCond app/public/%{SCRIPT_FILENAME} !-d

但它不起作用!我也尝试过使用 RewriteBase,但没有成功。

编辑:
我正在使用 mod_expires,我真的很想自动执行以下请求:

http://www.example.com/images/logo.42.png => app/public/images/logo.png  
http://www.example.com/javascripts/app.42.js => app/public/javascripts/app.js  

因此,如您所见,我希望在文件名和扩展名之间有可选数字,并且应该忽略该数字(它仅用于将来过期)。

以前,我发现:

RewriteRule ^(.*)\.(\d+)(_m_\d+)?\.([^\.]+)$ $1.$4 [QSA]  

但我真的不明白它是如何工作的,它在我的示例中是否总是有效(可能有多个扩展)?

谢谢!

【问题讨论】:

    标签: apache .htaccess mod-rewrite apache2


    【解决方案1】:

    试试这个:

    /.htaccess

    RewriteEngine on
    RewriteRule    ^$ app/public/    [L]
    RewriteRule    (.*) app/public/$1 [L]
    

    /app/.htaccess

    RewriteEngine on
    RewriteRule    ^$ public/    [L]
    RewriteRule    (.*) public/$1 [L]
    

    /app/public/.htaccess

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
    

    最后,在你的 /app/public/ 中创建一个 index.php 并在此处放置一个调度程序:

    <pre>
    <?php
    
    function dispatch($action, $request) {
    
        echo 'action: ' . $action;
        echo "\nparameters: " ;
        print_r($request);
    }
    
    $fragments = explode('/', $_GET['url']);
    dispatch($fragments[0], array_slice($fragments, 1));
    
    ?>
    </pre>
    

    现在说尝试访问:

    # these will go through php
    /controller/action
    /post/create
    /post/delete/1
    
    # these are static files
    /stylesheets/
    /foo/bar/myfile.txt
    

    【讨论】:

    • 我得到 500,在重写日志中,看起来他进入了不定式循环。但我不明白为什么,[L] 应该意味着它是最后的,对吧?另外,如果我理解得很好,您会将所有内容重定向到 app/public,对吗? index.php 部分呢?对不起,如果我理解错了!
    • @mfolnovich 抱歉,我没有粘贴其余文件
    • 嘿,tnx 为您解答。现在,它似乎适用于静态文件,但是: 1. 对于空路径,它显示 app/public 2. 对于真实请求,它崩溃并在日志中显示: script '/var/www/projects/petasite/app /public/index.php' 未找到或无法统计,我尝试放置 ../../index.php?url=$1,但它导致 500。编辑:无法弄清楚如何在 cmets 中放置换行符: S
    • @mfolnovich 您需要在 /app/public 中创建一个 index.php,它充当调度程序。
    • 嗯,有什么办法可以避免其他 index.php?如果没有,我想没有其他解决方案,所以 tnx 很多! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2012-03-13
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多