我最近在本地机器上安装了Apache 2.4,并使用PHP-FPM与PHP 5.4.8一起安装。
一切都很顺利(过了一段时间…),但仍然有一个奇怪的错误:
我为这样的PHP-FPMconfiguration了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()
(它只是一个testing文件)。
如果我调用一个目录然而,我得到一个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>
但问题是:它总是redirect,因为在http://localhost/
自动http://localhost/index.php
被请求,因为
DirectoryIndex index.php index.html
好吧,所以我想“也许先检查一下是否有文件给代理服务器:
<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>
现在完全重写不起作用了…
现在我有这个解决scheme:
<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(带有完整path和绝对path),然后进行重写。
在子目录中使用URL重写时,这不起作用,对于像http://localhost/index.php/test/
这样的URL也失败了。
有任何想法吗?
经过几个小时的search和阅读Apache文档,我想出了一个允许使用池的解决scheme,并且允许.htaccess中的Rewrite指令即使在URL包含.php文件时也可以工作。
<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。
我希望这个解决scheme也能帮助你。
我昨天也遇到了这个问题–Apache 2.4从Debian /实验中移出Debian / unstable,迫使我处理这个新东西; 当然不在我们的生产服务器上)。
在阅读了数以百万计的网站之后,Apache文档,错误报告和错误日志中的debugging输出,我终于得到了它的工作。 不, 没有套接字的FPM支持 。 Debian的默认configuration已经有一段时间了,所以Debian的用户也必须改变它。
以下是适用于CakePHP站点和PHPMyAdmin(后者需要一些configuration,如果你使用Debian软件包,虽然),所以我可以确认, mod_rewrite
仍然按照预期做的花式URL重写。
通知DirectoryIndex index.php
,这可能是你的configuration没有为“文件夹”工作的原因(至less这是什么在这里不工作)。
我仍然File not found.
对于目录,但只有在没有可以parsing的索引文件的情况下。 也想摆脱这一点,但现在并不那么重要。
<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>
上面的虚拟主机和根目录下的.htaccess完全兼容,就像这样:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] </IfModule>
虽然我只是重写到根目录的index.php,但是我不完全明白你URL rewriting inside a subdirectory
意思。
(哦,您必须确保Xdebug不会与您的系统上的FPM冲突,他们希望使用相同的端口。
这是我得到的。 这似乎工作确定。 我把Drupal放在一个子目录下,重写工作,目录索引工作,PATH_INFO工作。
RewriteEngine On RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$ RewriteCond %2 -f RewriteRule . fcgi://127.0.0.1:9000/%1 [L,P] RewriteOptions Inherit
我试图做这样的事情,而不重写(“如果”等),但我什么都不能工作。
编辑:请注意,如果你要实现这个共享托pipe服务提供商,这可能是一个安全问题。 它将允许用户将PHP脚本传递给任意的fcgi代理。 如果每个用户都有一个独立的池,那么就会导致特权提升。
所有你需要做的是设置:
ProxyErrorOverride on
不要忘记设置客户页面:
ErrorDocument 404 /path/to/error_page_file
解决这个问题的最佳方法是打开mod_proxy和mod_rewrite和php-fpm的debugging日志。 在apache 2.4中,现在只能打开特定模块的debugging日志。 http://httpd.apache.org/docs/current/mod/core.html#loglevel每个模块和每个目录的configuration可在Apache HTTP Server 2.3.6及更高版本中使用
也许你在目录上双斜杠?
这是我使用的,它工作正常:
<LocationMatch ^(.*\.php)$> ProxyPass fcgi://127.0.0.1:9000/home/DOMAINUSER/public_html$1 </LocationMatch>
又一个解决scheme(需要Apache> = 2.4.10) – 在虚拟主机内部:
# define worker <Proxy "unix:/var/run/php5-fpm-wp.bbox.nuxwin.com.sock|fcgi://domain.tld" retry=0> ProxySet connectiontimeout=5 timeout=7200 </Proxy> <If "%{REQUEST_FILENAME} =~ /\.php$/ && -f %{REQUEST_FILENAME}"> SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1 SetHandler proxy:fcgi://domain.tld </If>
所以在这里,PHP的fcgi处理程序只有在文件存在并且名称与PHP文件扩展名匹配时才会被设置。
顺便说一句:对于那些有想法将ProxyErrorOverride设置为On的请注意,这是一个坏主意。 这个指令的用法不是没有造成任何问题。 例如,任何发送诸如503的HTTP代码的PHP应用程序都会导致意外的结果。 在任何情况下,缺省的error handling程序都会涉及,而对于提供API的PHP应用程序来说,这确实是一个不好的行为。
我在处理这个问题时遇到的一件事是,如果你使用以下的组合:
chroot = /path/to/site chdir = /
在您的fpm池configuration中,不要将完整path传递给ProxyPass
指令。
ProxyPass fcgi://127.0.0.1:9020/$1
但是 – 只有 – 如果该端口上的池是chroot。
Linode在这个问题上有一个很好的教程
基本上你为整个服务器设置一个处理程序,它可以捕获任何php脚本并将它们传递给fast-cgi。
我不确定问题是否有关系,但是我在这里find了一个部分工作的解决scheme:
这个技巧似乎在增加一个? 字符在.htaccess重写规则,例如使用:
RewriteRule ^(.*)$ index.php?/$1 [L,NS]
代替:
RewriteRule ^(.*)$ index.php/$1 [L,NS]
问题的根源似乎是Apache 2.4.25的mod_rewrite的一个变化。 我已经使用了Apache trace1日志级别来观察在通过index.php / $ 1之后传递$ 1到php-fpm的“循环”。 $ 1生成“AH01071:有错误”主脚本未知\ n'“错误。
希望这个小小的消息帮助别人解决他们的问题。