我最近在本地机器上安装了 Apache 2.4,并使用 PHP-FPM 安装了 PHP 5.4.8。
一切都进行得相当顺利(过了一会儿......)但仍然有一个奇怪的错误:
我像这样为 PHP-FPM 配置了 Apache:
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1
</VirtualHost>
它有效,例如如果我调用http://localhost/info.php
我得到正确的phpinfo()
(它只是一个测试文件)。
但是,如果我调用目录,则会收到 404 错误File not found.
,错误日志中如下内容:
[Tue Nov 20 21:27:25.191625 2012] [proxy_fcgi:error] [pid 28997] [client ::1:57204] AH01071: Got error 'Primary script unknown\n'
更新
我现在尝试使用 mod_rewrite 进行代理:
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
但问题是:它总是重定向,因为http://localhost/
自动http://localhost/index.php
请求,因为
DirectoryIndex index.php index.html
更新 2
好的,所以我认为“也许先检查是否有一个文件要提供给代理:
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
现在完全重写不再起作用了......
更新 3
现在我有这个解决方案:
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond /Users/apfelbox/WebServer/%{REQUEST_FILENAME} -f
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
首先检查是否有文件要传递给 PHP-FPM(使用满的和绝对路径),然后进行重写。
在子目录内使用 URL 重写时,这不起作用,对于类似这样的 URL,它也会失败,http://localhost/index.php/test/
所以回到原点。
有任何想法吗?
答案1
经过几个小时的搜索和阅读 Apache 文档后,我找到了一个解决方案,它允许使用池,并且即使 url 包含 .php 文件,也允许 .htaccess 中的 Rewrite 指令起作用。
<VirtualHost ...>
...
# This is to forward all PHP to php-fpm.
<FilesMatch \.php$>
SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"
</FilesMatch>
# Set some proxy properties (the string "unique-domain-name-string" should match
# the one set in the FilesMatch directive.
<Proxy fcgi://unique-domain-name-string>
ProxySet connectiontimeout=5 timeout=240
</Proxy>
# If the php file doesn't exist, disable the proxy handler.
# This will allow .htaccess rewrite rules to work and
# the client will see the default 404 page of Apache
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
RewriteRule (.*) - [H=text/html]
</VirtualHost>
根据 Apache 文档,SetHandler 代理参数需要 Apache HTTP Server 2.4.10。
我希望这个解决方案也能帮助您。
答案2
我昨天也遇到了这个问题——Apache 2.4 移出了Debian/实验进入Debian/不稳定迫使我处理这些新东西;当然不是在我们的生产服务器上;)。
在阅读了数百万个网站、Apache 文档、错误报告和错误日志中的调试输出后,我终于让它工作了。不,有不支持带套接字的 FPM,但是。默认的 Debian 配置已经使用套接字一段时间了,因此 Debian 用户也必须进行更改。
以下是适用于 CakePHP 网站和 PHPMyAdmin 的操作(如果您使用 Debian 软件包,后者需要一些配置),所以我可以确认它mod_rewrite
仍然可以按预期进行花哨的 URL 重写。
请注意DirectoryIndex index.php
,这可能是您的配置不适用于“文件夹”的原因(至少在这里不起作用)。
我仍然能获取File not found.
目录,但前提是没有索引文件可以解析。我也想摆脱它,但目前它并不是那么重要。
<VirtualHost *:80>
ServerName site.localhost
DocumentRoot /your/site/webroot
<Directory />
Options FollowSymlinks
DirectoryIndex index.php
AllowOverride All
Require all granted
</Directory>
<LocationMatch "^(.*\.php)$">
ProxyPass fcgi://127.0.0.1:9000/your/site/webroot
</LocationMatch>
LogLevel debug
ErrorLog /your/site/logs/error.log
CustomLog /your/site/logs/access.log combined
</VirtualHost>
上述 vhost 与根目录中的 .htaccess 配合得很好,如下所示:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
我不太明白你的意思URL rewriting inside a subdirectory
(我只是重写了根的 index.php)。
(哦,你必须确保 Xdebug 不会与你系统上的 FPM 冲突,因为它们开箱即用,需要使用相同的端口。)
答案3
您需要做的就是设置:
ProxyErrorOverride on
并且不要忘记通过以下方式设置客户页面:
ErrorDocument 404 /path/to/error_page_file
答案4
这就是我得到的。它似乎工作正常。我将 Drupal 放在子目录中,它的重写工作正常,目录索引工作正常,PATH_INFO 工作正常。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %2 -f
RewriteRule . fcgi://127.0.0.1:9000/%1 [L,P]
RewriteOptions Inherit
我曾尝试在不使用重写(“如果”等)的情况下做这样的事情,但我无法让任何事情发挥作用。
编辑:请注意,如果您将其实现为共享托管提供商,则可能会出现安全问题。它将允许用户将 PHP 脚本传递给任意 fcgi 代理。如果您为每个用户设置一个单独的池,那么这将允许特权提升攻击。