WordPress多站点、自定义wp-content文件夹以及请求超过10个内部重定向限制

5
我正在编写一个 WordPress 插件,该插件使用类内的设置 API。因此,该类从内部调用 register_settings()、add_settings_field() 和 add_settings_section(),这很好地运行,但当我尝试提交表单时,出现服务器错误,并在日志中看到以下错误:
AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

我的WordPress安装有点奇怪。它基于Mark Jaquith的WordPress Skeleton repo,我已经将wp-content文件夹和wp-config.php文件移动到WordPress之外。

我也通过Vagrant运行WordPress,所以可能是服务器配置问题。然而,我刚刚尝试在标准WordPress安装中使用我的插件,它完美地工作。

我的WordPress目录看起来像这样(composer将WP安装到app目录中):

index.php
wp-config.php
wp-content/
app/

我已经在一个paste bin中添加了我的重写日志: http://pastebin.com/QKCFjULZ 我的.htaccess文件如下:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]


RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) /app/$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ /app/$2 [L]


RewriteRule . /index.php [L]

Options -indexes
</IfModule>
# END WordPress

我已经缩小了问题范围,不是类的问题。我将所有设置API函数移出类,并以标准方式加载它们。 - rugbert
1个回答

1
由于这些规则,您遇到了重定向循环。
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) /app/$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ /app/$2 [L]

事实上,您必须记住,即使进行重写,您的规则仍然会被评估。因此,如果您有/something/wp-xxx/yyy/zzz,它将在内部重写为/app/wp-xxx/yyy/zzz。但现在,正如您所看到的,您的规则将再次与新的uri /app/wp-xxx/yyy/zzz匹配。

证据,请查看您的日志

applying pattern '^([_0-9a-zA-Z-]+/)?(wp-.*)' to uri 'wp-admin/network/options.php',
rewrite 'wp-admin/network/options.php' -> '/app/wp-admin/network/options.php',

然后你有:

applying pattern '^([_0-9a-zA-Z-]+/)?(wp-.*)' to uri 'app/wp-admin/network/options.php',
rewrite 'app/wp-admin/network/options.php' -> '/app/wp-admin/network/options.php',

直到进行了10次重定向,它才会停止...
为了避免这种行为,您需要在规则中添加一些限制,以确保当它们不必要时不会被评估。一个简单的解决方法是使用负向先行断言模式,在重写之前确保当前请求不以“/app/”开头:
RewriteRule ^((?!app/)[^/]+/)?(wp-.+)$ /app/$2 [L]  

最终,你的htaccess文件可能是这样的。
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# Rule 1
RewriteRule ^([^/]+/)?files/(.+)$ wp-includes/ms-files.php?file=$2 [L]

# Rule 2
RewriteRule ^((?!app/)[^/]+/)?(wp-.+)$ /app/$2 [L,QSA]

# Rule 3
RewriteRule ^((?!app/)[^/]+/)?(.+\.php)$ /app/$2 [L,QSA] 

RewriteRule ^ index.php [L]

Options -Indexes
</IfModule>
# END WordPress

提醒:这三条规则仅在文件/文件夹不存在时执行。
例子:
- http://domain.tld/files/somethinghttp://domain.tld/xxx/files/something将被内部重写为/wp-includes/ms-files.php?file=something,感谢规则1。 - http://domain.tld/wp-something/somethingelsehttp://domain.tld/xxx/wp-something/somethingelse(其中xxx可以是除app之外的任何内容)将被内部重写为/app/wp-something/somethingelse,感谢规则2。 - http://domain.tld/file.phphttp://domain.tld/xxx/file.php(其中xxx可以是除app之外的任何内容)将被内部重写为/app/file.php,感谢规则3

谢谢你,抱歉我错过了回复。所以你添加的规则没有解决递归错误。我注意到浏览器中的 URL 从未改变以包括 /app,只是为了自己的了解,RewriteCond 是什么意思?如果 %{THE_REQUEST} 包含该模式,那么将其替换为 /app? - rugbert
重新阅读您的问题后,我注意到了一些问题并修改了我的答案中的代码。请仔细阅读底部的示例,并告诉我它是否符合您期望的行为。无论如何,使用此代码后,您都不应该再有循环。 - Justin Iurman
1
谢谢!没有我的递归错误,网站速度也更快了。 - rugbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接