以下是PHP-FPM(PHP 5.5)
php-cgi.exe -b 127.0.0.1:9000
以下是mod_proxy_fcgi(Apache 2.4)
第一种方式
<Files ~ "\.(php|phtml)$">
SetHandler "proxy:fcgi://127.0.0.1:9000/"
</Files>
第二种方式
<LocationMatch ^(.*\.(php|phtml))$>
ProxyPass fcgi://127.0.0.1:9000/$1
</LocationMatch>
第三种方式
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^([^\.]+\.(php|phtml))$ fcgi://127.0.0.1:9000/$1 [P,L]
</IfModule>
以上三种方式都会出现错误“未指定输入文件”。谁知道为什么?我该怎么做才能解决这个问题?
令人费解的是,只需改变尾随 /
到了 #
似乎解决了这个问题:
<Files ~ "\.(php|phtml)$">
SetHandler "proxy:fcgi://127.0.0.1:9000#"
</Files>
在试图理解这一点时,我将Apache设置为 LogLevel debug
(为简洁起见,删除了时间戳/模块/流程详细信息):
运用 /
得到:
mod_proxy_fcgi.c(911): [client ::1:60730] AH01076: url: fcgi://127.0.0.1:9000/E:/test/webroot/test.php proxyname: (null) proxyport: 0
mod_proxy_fcgi.c(920): [client ::1:60730] AH01078: serving URL fcgi://127.0.0.1:9000/E:/test/webroot/test.php
proxy_util.c(2154): AH00942: FCGI: has acquired connection for (*)
proxy_util.c(2208): [client ::1:60730] AH00944: connecting fcgi://127.0.0.1:9000/E:/test/webroot/test.php to 127.0.0.1:9000
proxy_util.c(2417): [client ::1:60730] AH00947: connected /E:/test/webroot/test.php to 127.0.0.1:9000
运用 #
得到:
mod_proxy_fcgi.c(911): [client ::1:60738] AH01076: url: fcgi://127.0.0.1:9000#E:/test/webroot/test.php proxyname: (null) proxyport: 0
mod_proxy_fcgi.c(920): [client ::1:60738] AH01078: serving URL fcgi://127.0.0.1:9000#E:/test/webroot/test.php
proxy_util.c(2154): AH00942: FCGI: has acquired connection for (*)
proxy_util.c(2208): [client ::1:60738] AH00944: connecting fcgi://127.0.0.1:9000#E:/test/webroot/test.php to 127.0.0.1:9000
proxy_util.c(2417): [client ::1:60738] AH00947: connected to 127.0.0.1:9000
关键的区别似乎是在最后一行,其中第二个(工作)方法似乎没有记录 什么 作为传递给PHP进程的值。
我无法解释这一点,无法在任何地方找到它。 (也许比我更愿意深入研究Apache和/或PHP来源进行调查的是一个勇敢的灵魂。)
请注意,除了跑步之外,我还没有测试过 phpinfo()
所以不会推荐它用于生产服务器。
编辑
这适用于PHP 7.0,但是使用PHP 5.6,我仍然会收到“未指定输入文件”错误。
编辑2
并使用Apache 2.4.25,但不是最近发布的2.4.26!
这似乎是CHANGES_2.4.26文件中明确提到的不兼容雷区:
mod_proxy_fcgi:返回2.4.20及更早的离开行为
SCRIPT_FILENAME环境变量中的“proxy:fcgi://”前缀
默认。添加ProxyFCGIBackendType以允许后端类型
指定这样可以在不影响的情况下恢复这些类型的修正
FPM。 PR60576 [Eric Covener,Jim Jagielski]
该 文件 已更新,以反映这一点:
根据此指令的设置更改的值的一个示例是SCRIPT_FILENAME。历史上使用mod_proxy_fcgi时,SCRIPT_FILENAME的前缀是字符串“proxy:fcgi://”。这个变量是一些通用的FastCGI应用程序将读取的脚本输入,但PHP-FPM会删除前缀,然后记住它正在与Apache交谈。在2.4.21到2.4.25中,服务器自动剥离了这个前缀,破坏了PHP-FPM在某些情况下检测和与Apache互操作的能力。
我认为这是mod_proxy_fcgi中的一个错误,它连接到Apache 2.4.12以后解决的问题:
mod_proxy_fcgi:从SCRIPT_FILENAME中删除代理:balancer://前缀传递给fastcgi后端。 [Eric Covener]
这是一个链接
不幸的是,它不够好,因为Apache正在向SCRIPT_FILENAME发送一个起始斜杠,类似于 \ C:\ fileName.php,它不会被解析为本地文件名,并且永远不会被执行。您可以使用在FastCGI端口上侦听的网络嗅探器(Wireshark)来验证这一点。
我很高兴看到这个问题正式解决,因为我不自信地重新编译Apache,所以我使用的是 apachelounge。
也许你没有把我弄好。
在修复之前它是: 代理:平衡器:// \ C:\ fileName.php
修复后它是: \ C:\ fileName.php
哪些都是Windows中的无效文件名,而在思考Linux的时候没有驱动器号,所以它就变成了 \ fileName.php 这是有效的。解决方法是删除起始斜杠并重新编译。