Apache + PHP-FPM 与 WordPress 多站点问题

前些天切换服务器到 CentOS 7 上的 Apache 2.4,在使用 MPM event + PHP-FPM 的时候遇到了 ProxyPassMatch 与运行子目录(SubDirectory)形式的 WordPress 多站点(MultiSite)不匹配的问题。结果访问子站点的仪表盘就发现 css 文件和 js文件无法正确加载,遭遇 404 错误。这里是水景一页的修正方法。

捣鼓了很长时间都没解决,甚至一度切回了 Apache 的 prefork 模式。研究了很久的 MPM event + PHP-FPM 的配合方式,才发现问题出在 Apache 配置文件中使用 ProxyPassMatch 传递请求给 PHP-FPM 的文件名正则表达式匹配规则上面。就像 phpMyAdmin 使用的 ProxyPassMatch 与一般的不同一样,针对 WordPress 多站点也需要增加一条匹配规则。这里只讨论了 WordPress 使用子目录方式启用多站点功能的情况。

1. 普通非多站点的 WordPress 情况

对于没有运行多站点模式的 WordPress,按照一般的 event + PHP-FPM 协作规则,参考这里,只需要设置好 PHP-FPM 的监听方式为,

listen = 127.0.0.1:9000

然后给每个 Apache 中定义的虚拟主机配置文件中的 <VirtualHost *:80> 中增加一条,

<IfModule mpm_event_module>
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/path/to/webroot/$1
</IfModule>

即可正常解析 Apache 接收到的访问 php 页面请求。

2. 对于启用了多站点的 WordPress

启用了子目录形式的多站点之后,WordPress 可以在一个安装下展示多个站点,网址形式就是,

http://cnzhx.net/liveinmanchester/

直接访问域名是主站点,后面的 liveinmanchester 就是一个子站点。水景一页这里开启了多个子站点,其中一些的链接显示在了本页面的右上角。

前面的基本的 ProxyPassMatch 规则对主站点来说没问题,但是对子站点来说就不对了。因为子站点的链接里都带上了 /liveinmanchester/ 这么一节,比如仪表板中的文章页面,

http://cnzhx.net/liveinmanchester/wp-admin/edit.php

实际访问的 php 文件在服务器的系统应该是,

http://cnzhx.net/wp-admin/edit.php

这就导致 PHP-FPM 按照访问路径匹配不到实际的 edit.php 文件从而出错。

类似的还有位于根目录的一些 wp- 开头的文件。

解决办法就是,将一般的 ProxyPassMatch 规则改为,

<IfModule mpm_event_module>
    ProxyPassMatch ^/([_0-9a-zA-Z-]+/)?(wp-(activate|blog-header|comments-post|config|cron|links-opml|load|login|mail|settings|signup|trackback)\.php(/.*)?)$ fcgi://127.0.0.1:9000/srv/www/cnzhx.net/public_html/$2
    ProxyPassMatch ^/([_0-9a-zA-Z-]+/)?(xmlrpc\.php(/.*)?)$ fcgi://127.0.0.1:9000/srv/www/cnzhx.net/public_html/$2
    ProxyPassMatch ^/([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes)/.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/path/to/webroot/$2
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/path/to/webroot/$1
</IfModule>

前 3 行 ProxyPassMatch 规则是仿照 WordPress 多站点模式中的 Mod_Rewrite 重写访问链接的规则写的,目的就是去掉网址中的子站点目录那一节,使得 PHP-FPM 能找到正确的 php 文件。

3. 其它问题

除了上一节提到的访问子站点仪表盘时可能定位不到实际的 php 文件的问题外,对于新部署的 WordPress 多站点,因为 WordPress 会在部署多站点的时候调节主站点的网站目录结构(是网址结构,而不是实际的文件结构),也可能会遇到问题。比如分类(category)和标签(tag)页面。

启用多站点前,WordPress 的一般分类(category)和标签(tag)页面网址为:

cnzhx.net/category/vps
cnzhx.net/tag/vps

而启用了子目录形式的 WordPress 多站点以后,它们的网址变成了,

cnzhx.net/blog/category/vps
cnzhx.net/blog/tag/vps

于是也会出现类似上面 2 中提到的无法找到页面的问题,遭遇 404 错误。

此时,只需要在 WordPress 主站点的仪表盘中的工具 –> 固定链接页面的 Category base 和 Tag base 那里分别填写 categorytag 并保存即可。(当然也可以填写别的短语,比如 cat 和 t 。)就能解决打开此类页面出现 404 not found 错误的问题。

相信这样的问题在 Apache 2.4.10 中启用 SetHandler 方式后就不会出现了。©

本文发表于水景一页。永久链接:<http://cnzhx.net/blog/apache-php-fpm-and-wordpress-multisite/>。转载请保留此信息及相应链接。

4 条关于 “Apache + PHP-FPM 与 WordPress 多站点问题” 的评论

  1. 博主是对Apache情有独钟呢,遇到这么多问题还坚守。
    既然都上PHP-FPM了,有把Apache和Nginx做过比对吗?

雁过留声,人过留名

您的电子邮箱地址不会被公开。 必填项已用 * 标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>