首页 > 解决方案 > 在 htaccess 中结合静态和动态路由

问题描述

我正在处理一些具有大量 htaccess 重定向的遗留代码,如下所示:

    Options +FollowSymLinks
    RewriteEngine On

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

    RewriteRule ^login/([-A-z0-9]+)*$ ./login.php?id=$1 [R=302,NC,QSA,L]
    RewriteRule ^my-account/*$ ./my-account.php [R=302,NC,L]
    RewriteRule ^legacy-path-1/*$ ./god-knows-what.php [R=302,NC,L]
    RewriteRule ^legacy-path-2/*$ ./static-dynamic-page.php [R=302,NC,L]
    RewriteRule ^legacy-why-would-you-code-this-path/*$ ./king-of-spagetti-code.php [R=302,NC,L]
    .............

        # about dozen of similar lines as above
    .............
    #my last line in that mess
    RewriteRule ^another-static-link/([-A-z0-9]+)*$ ./another-one-of-many-copy-paste-pages.php?pool_id=$1 [R=302,NC,QSA,L]

但是,我们正在添加新组件,并且我实现了一个使用路由的自定义构建的轻型框架。

在不重写整个代码的情况下,我需要将与上述任何规则都不匹配的 URL 发送到app.php,它会根据路由规则进行路由。

所以当我在 .htaccess 末尾添加这一行时

RewriteRule ^(.*)$ app.php?route_query=$1 [L,QSA]

尽管有上面的 [L] 标志, htaccess 仍然处理 app.php 的所有内容(自然会导致错误)。

如果 URL 匹配,我如何停止 .htaccess 以比匹配行更进一步?

我认为 [L] 标志可以做到这一点。但事实并非如此。

我考虑过重写静态路由,但这超出了我们协议的范围。

谢谢你的帮助。

标签: apache.htaccessmod-rewriteapache2

解决方案


RewriteCond范围RewriteRule 适用于非常下一个。从您的示例中,仅检查以下规则RewriteRule ^login/([-A-z0-9]+)*$ ./login.php?id=$1 [R=302,NC,QSA,L]。在您的情况下,当您在末尾添加通配符规则时,它总是一次又一次地匹配(您创建了一个透明的无限重写循环)。

你需要做的是在开始时忽略现有的文件夹/文件,然后做你的烂摊子

Options +FollowSymLinks
RewriteEngine On

# don't touch existing folders/files
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# your mess here

RewriteRule ^(.*)$ app.php?route_query=$1 [L,QSA]

推荐阅读