通过 ProxyPassMatch 作为处理程序转发 PHP 请求,或者仅当文件存在时

通过 ProxyPassMatch 作为处理程序转发 PHP 请求,或者仅当文件存在时

我正在迁移我的服务器以使用 mod_proxy_fcgi 和 php-fpm 而不是 mod_php。Apache 能够将 .php 请求转发到 fcgi 代理,并且 PHP 可以正确执行。我已使用以下方法使其正常工作:

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1

不幸的是,即使文件不存在,Apache 也会将所有 .php 请求转发到代理。这会导致一些问题。我的 ErrorDocument 规则没有被调用,并且DirectoryIndex index.php index.html不会回退到 index.html。

我能够使用 mod_rewrite 修复这些问题:

RewriteEngine On                                                           
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$                       
RewriteCond /var/www/html/%2 -f                                   
RewriteRule . fcgi://127.0.0.1:9000/var/www/html/%1 [P] 

但是,Apache 文档不推荐RewriteRule:“这是因为该标志触发了默认工作器的使用,而默认工作器不处理连接池。”

理想情况下,我想我要么在 FilesMatch 块中使用 ProxyPass(当前不受支持),要么定义一个通过 fcgi 代理的新处理程序并使用它来处理 .php 请求,类似于 mod_php 所做的。

有什么建议可以模拟标准 mod_php 设置但实际上通过 fcgi 进行代理?

答案1

一个选项是安装 mod_proxy_handler: https://gist.github.com/progandy/6ed4eeea60f6277c3e39

或者您可以等待 Apache 2.4.10,它应该包含该模块。

基本上,该模块允许您执行以下操作:

#tcp
<FilesMatch \.php$>
SetHandler proxy:fcgi://localhost:9000
</FilesMatch>

#uds
<FilesMatch \.php$>
    SetHandler "proxy:unix:/path/to/socket.sock|fcgi://./"
</FilesMatch>

答案2

仅作为一行记录:

AddHandler "proxy:unix:/path/to/socket.sock|fcgi://./" .php

您需要最新的 Apache 2.4(RedHat 已将其移植回 2.4.6)

奥利弗

答案3

当文件不存在时我遇到了同样的问题,显示“未找到文件。”消息,这解决了我的问题并允许我设置一个 404 页面:

<VirtualHost *:80>

---------- content --------

DocumentRoot /home/user/public_html/domain.tld

#this disables php execution if you wish to show only html files
#ProxyPass /errors !

ProxyErrorOverride On
# /errors folder is located in public_html
ErrorDocument 404 /errors/404.php


</VirtualHost>

答案4

我遇到了与 ide 完全相同的问题,并且花了比我预期更长的时间尝试解决这个问题。由于这是我能找到的唯一一篇帮助我充分解决问题的帖子或文章,所以我想将我的解决方案添加到其中。

我的配置:

  • Ubuntu 14.04
  • Apache 2.4.20
  • PHP-FPM 5.5.9-1ubuntu4.17 (fpm-fcgi)(构建于:2016 年 5 月 19 日 19:08:26)

我遇到了一些额外的挑战:

  1. 我的 ErrorDocument 处理程序是一个 PHP 文件。
  2. 我的文档根目录的 .htaccess 文件中有一堆 RedirectPermanent 指令。这些指令没有得到执行,因为在评估重定向规则之前,请求被代理到 PHP-FPM。
  3. FilesMatch 对我来说不够用,因为我使用 URL 重写的方式与 Wordpress 类似。例如 /mydir/mypath.html 指向 /mydir/script.php。我无法让它匹配重写的 URL,不过也许我忽略了一些东西?
  4. 我能够让 misterich 的方法发挥作用,但在阅读了 Apache 的绩效警告,我决定进一步深入研究。

我的解决方案基本上是这样的:

  1. 拦截并重定向对不存在的目录和文件的请求并将其重写为错误处理程序 PHP 文件。
  2. 使用另一个重写规则将我重写的错误请求路由到 PHP-FPM。
  3. 使用 ProxyPassMatch 将所有其他请求路由到 PHP-FPM。

为了解决 301 重定向(#2),我将简单地利用错误处理程序来发出重定向。

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^.*\.php$ /error.php?error=404&requestUri=$1

RewriteCond %{REQUEST_FILENAME} ^/(error.php)$
RewriteCond %{DOCUMENT_ROOT}/%1 -f
RewriteRule . fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/%1   [P]

# PHP-FPM
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/mysite.com"

相关内容