Wordpress 网站子目录中的 Yii2 应用程序:无法启用漂亮的网址

Yii2 app in a subdirectory of a Wordpress website: cannot enable pretty urls

我正在尝试在 Wordpress 位于根目录的共享环境中部署一个基本的 Web 应用程序。 Yii2 应用程序在 /subfolder.

我正在关注 this guide。在 root 的 .htaccess 中我添加了:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /subfolder
    RewriteCond %{REQUEST_URI} ^/subfolder
    RewriteCond %{REQUEST_URI} !^/subfolder/web
    RewriteRule ^assets/(.*)$ /web/assets/ [L]
    RewriteRule ^css/(.*)$ /web/css/ [L]
    RewriteRule ^js/(.*)$ /web/js/ [L]
    RewriteRule ^images/(.*)$ /web/images/ [L]
    RewriteRule (.*) /web/ [L]

    RewriteBase /subfolder
    RewriteCond %{REQUEST_URI} ^/subfolder
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /web/index.php
</IfModule>

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

但是添加了这些规则后,所有 Wordpress 的页面都通过 Yii 处理(或尝试),因此这会破坏博客安装。这是捕获所有页面的第一块规则,但我不明白为什么两个 RewriteCond 应该只拦截 Yii 应用程序 URI。我检查了 mod_rewrite 文档,但不明白哪里出了问题。任何帮助表示赞赏。谢谢

RewriteBase /subfolder

您不能在同一个 .htaccess 文件中设置多个 RewriteBase 指令。 last 实例“获胜”并控制整个文件。因此,在您发布的 .htaccess 文件中,WordPress 代码块中设置的 RewriteBase / 是实际为该文件设置的内容。

然而,none 的指令实际上使用了 RewriteBase 指令 - 所以 none 的 RewriteBase 指令实际上在做任何事情。 RewriteBase 指令仅适用于在 RewriteRule 中设置了 relative 路径(不是以 斜线 开头) 替换 字符串。

but I don’t understand why as the two RewriteCond should intercept only the Yii app URIs.

RewriteCond %{REQUEST_URI} ^/subfolder
RewriteCond %{REQUEST_URI} !^/subfolder/web
RewriteRule ^assets/(.*)$ /web/assets/ [L]

大概是您指的是这两个 RewriteCond 指令...在这种情况下,这两个 条件 并没有真正做任何事情。 RewriteCond 指令仅适用于随后的第一个 RewriteRule 指令,因此它仅适用于重写 assets.

的指令

但是,此 RewriteRule 匹配文档根目录中的 /assets,而不是 /subfolder/assets,这可能是要求 - 因此这些规则将无法匹配。

But with these rules added all Wordpress’ pages are handled (or attempted) through Yii, so this breaks the blog installation.

这些规则肯定会“破坏博客安装”,但是,它们似乎并没有达到“通过 Yii”处理请求的程度。没有任何东西可以将请求重写为 /subfolder。但是,以下指令无条件地将 everything 重写到文档根目录中的 /web 目录(可能不存在) - 所以这肯定会“破坏”所有 WordPress URLs.

RewriteRule (.*) /web/ [L]

事实上,我本以为这会创建一个重写循环(500 内部服务器错误响应)?!除非你在文档根目录下有一个子目录 /web,它还包含一个包含 mod_rewrite 指令的 .htaccess 文件?但这似乎不太可能,因为 /web 目录应该在 /subfolder 目录中?

请尝试以下操作:

RewriteEngine On

RewriteRule ^(subfolder)/(assets|css|js|images)/(.*) /web// [L]
RewriteRule ^(subfolder)/((?!web).*) /web/ [L]

RewriteRule ^subfolder/web/index\.php - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(subfolder)/. /web/index.php [L]

# BEGIN WordPress
:

不需要 <IfModule> 包装器。或者 RewriteBase 指令。

或者

但是,最好将这些指令移动到项目根目录中它们自己的 .htaccess 文件中,即。 /subfolder/.htaccess - 我相信这是链接的“指南”所暗示的。这使两个项目完全分开。并避免必须在指令中显式包含 /subfolder

此外,在 web 子目录中创建另一个 .htaccess 文件,即。 /subfolder/web/.htaccess。这又是在链接的“指南”中建议的。但是,这也不需要额外的指令来路由父 .htaccess 文件中的请求。

例如,将这些更改放在一起,文档根目录中的 /.htaccess 文件应该只有 WordPress 指令。然后...

/subfolder/.htaccess

RewriteEngine On

RewriteRule ^((?:assets|css|js|images)/.*) web/ [L]
RewriteRule ^((?!web).*) web/ [L]

/subfolder/web/.htaccess

RewriteEngine On

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

同样,这里不需要 RewriteBase 指令 - 事实上,在这里使用 RewriteBase 可以说会使事情复杂化。在 /subfolder/web/.htaccess 文件中时,所有相对 URL 路径都是相对于该目录的。

因此,请求 /subfolder/foo/subfolder/.htaccess 文件内部重写为 /subfolder/web/foo。然后由 /subfolder/web/.htaccess 文件捕获(防止重写循环)并在内部重写为 /subfolder/web/index.php(前提是 foo 不作为物理文件存在)。