如何确定是否正在使用FastCGI运行PHP脚本

19
我有一个托管的网站,在配置Joomla(在IIS7 + Win Server 2008上运行Joomla + PHP + MySQL)时遇到了问题。我在本地机器上有类似的配置(在IIS7 + Vista x64上运行Joomla + PHP + MySQL),所以我至少能够按照各种教程中显示的说明进行设置。
托管网站的这个问题是,我无法在Joomla中启用任何SEO设置(甚至不是第一个设置,“搜索引擎友好的URL”)。我要么得到404(文件未找到)或者URL被正确重写但始终显示主页的内容。在我的主页设备上也出现了类似的问题,结果证明这是因为我没有使用FastCGI来托管php,所以我决定在托管网站上进行调查。
无论如何,我注意到在托管网站上托管joomla的目录的web.config文件中有以下行:
<add name="Plesk_Handler_3522909676" path="*.php" verb="*" modules="IsapiModule" scriptProcessor="c:\program files (x86)\parallels\plesk\additional\pleskphp5\php5isapi.dll" resourceType="Either" />

从过去的经验来看,我知道当php不运行在fastCGI下时会出现一些问题。我注意到根文件夹中的web.config使用了以下行:

<add name="Plesk_Handler_0286090609" path="*.php" verb="*" modules="CgiModule" scriptProcessor="c:\program files (x86)\parallels\plesk\additional\pleskphp5\php-cgi.exe" resourceType="Either" /> 

我将它复制到了 joomla 目录下的 web.config 文件中,它的行为不同了,但仍然无法正常工作。如果我加载一个在 joomla 目录下运行 phpInfo() 的 .php 文件,在 “Server API” 下会显示 CGI/FastCGI 。这是 FastCGI 被使用的确认 吗?为什么 web.config 中的处理程序指向 modules="CgiModule" 而不是 modules="FastCgiModule" (我甚至不确定是否存在 FastCgiModule,但我对 CgiModule 的提及感到怀疑)。

这是一个托管的网站,所以据我所知,我无法访问 ApplicationHost.config 文件...

8个回答

32

以下是一个简单测试:

  1. 创建一个包含以下内容的phpinfo.php文件:

 <?php phpinfo(); ?> 

内部;

  1. 请求http://yoursite.com/phpinfo.php/foobar?foo=bar

  2. 检查phpinfo输出并查找_SERVER["REQUEST_URI"]。

如果此变量缺少,则使用CGI。 如果该变量存在并正确设置为/phpinfo.php/foobar?foo=bar,则使用ISAPI或FastCGI。 在输出的顶部附近查找Server API; 它应该设置为ISAPI(表示正在使用ISAPI)或CGI / FastCGI(表示已经排除了CGI,因此正在使用FastCGI)。


1
$_SERVER['REQUEST_URI'] 可以在 CGI 和 FastCGI 中正确显示,而服务器 API 可能会显示“CGI/FastCGI”用于 CGI 和 FastCGI。一个区别是,在 FastCGI 中 $_SERVER["REDIRECT_HANDLER"] 可能会显示 php-fastcgi,但这也不能确认正在使用“FastCGI”,因为“php-fastcgi”只是配置文件中使用的变量名。 - Silver Moon
@Jimmy,这个答案非常需要引用(http://xkcd.com/285)。另外,你描述的方法听起来有点“hacky”,是否有更好、更健壮的方法可以直接确定设置呢? - Pacerier
@Pacerier,这对我和许多其他人都有效。我找不到更好的方法,但如果你有更好且更健壮的答案,请随意发布。这是我自己想出来的,因此没有引用。 - Jimmy
@Jimmy,这个问题是在问“如何确定FastCGI正在用于运行php脚本”,这意味着页面上的人们没有办法验证您的答案是否确实按照所述工作。因此,我说需要引用。一旦一个答案达到+8票,其他人就会不加思考地点赞或尝试。还请参见https://dev59.com/-nRB5IYBdhLWcg3weXOX#1181327。 - Pacerier

6

谢谢 Gregor,这似乎是一个很好的简单解决方案。 - AdamJones

5
您可以使用(在CentOS上)apachectl -M命令,它会显示哪些模块已启用:
apachectl -M:

file_cache_module (shared)
mem_cache_module (shared)
version_module (shared)
fastcgi_module (shared)

也适用于Ubuntu,尽管我不得不使用sudo。 - Sam

2

很遗憾,对于我来说检查\_SERVER["REQUEST_URI"]并没有起作用。使用CGIFastCGI时,它总是显示/phpinfo.php/foobar?foo=bar

检查Server API = CGI/FastCGI也无法解决问题 - 它只告诉您编译版本的php支持哪些接口,而不是正在使用哪个接口。然而,我找到了另一种可能更可靠的方法。

放置一个名为phpinfo.php的文件,其中包含文本:<? php phpinfo(); ?>

检查变量\_ENV["REDIRECT_HANDLER"]
如果设置为php5-fastcgi(或其他类似于fastcgi的东西),则请求很可能通过FastCGI进行。如果设置为application/x-httpd-php(或我认为与上述内容不同的内容),则使用CGI

但是,一种可靠的方法是运行一个小测试。 您需要ab(Apache Bench)工具。
在有CGI和没有CGI的情况下,从另一台计算机运行此命令:

ab -c 100 -n 1000 http://yourdomain.com/path/phpinfo.php

请检查Time taken for tests:这一行。在我的电脑上,通过1.3Mbps的ADSL连接访问VPS时,FastCGI完全占用了它的带宽,而使用CGI只能填满其一半。

希望这可以帮到您。


1

你应该从中看到一个引用

<?php
phpinfo();
?>

服务器 API = CGI/FastCGI


但这是确定的吗?我的主机说他们不支持FastCGI;上面的web.config说他们正在使用CGI,而不是FastCGI;然而,在phpinfo()中我仍然看到Server API = CGI/FastCGI。 - Jimmy

0

这对我有用。

/**
 * return phpinfo() results as an array
 *
 * @credit http://php.net/manual/en/function.phpinfo.php#106862
 * @param void
 * @return array
 */
function phpinfo_array(){
    ob_start();
    phpinfo();
    $info_arr = array();
    $info_lines = explode("\n", strip_tags(ob_get_clean(), '<tr><td><h2>'));
    $cat = 'general';
    foreach($info_lines as $line){
        preg_match('/<h2>(.*)<\/h2>/', $line, $title) ? $cat = preg_replace('/\s+/', '_', strtolower(trim($title[1]))) : null;
        if(preg_match('/<tr><td[^>]+>([^<]*)<\/td><td[^>]+>([^<]*)<\/td><\/tr>/', $line, $val)){
            $subcat = preg_replace('/\s+/', '_', strtolower(trim($val[1])));
            $info_arr[$cat][$subcat] = $val[2];
        } elseif(preg_match('/<tr><td[^>]+>([^<]*)<\/td><td[^>]+>([^<]*)<\/td><td[^>]+>([^<]*)<\/td><\/tr>/', $line, $val)){
            $subcat = preg_replace('/\s+/', '_', strtolower(trim($val[1])));
            $info_arr[$cat][$subcat] = array('local' => $val[2], 'master' => $val[3]);
        }
    }
    return $info_arr;
}


// output proper response code
$phpinfo = phpinfo_array();
$configure = (@isset($phpinfo['general']['configure_command'])) ?: null;

// properly account for FastCGI
if ($configure && preg_match('/--enable-fastcgi/', $configure)){
    // fastcgi response
    header('Status: 403 Access is forbidden');
} else {
    // http response
    header('HTTP/1.0 403 Access is forbidden');
}

2
脚本如何工作?脚本做什么? - Pacerier

0

确保最初设置是当fastcgi未运行时脚本完全失败。然后,当它工作时,您就会知道fastcgi守护程序是原因。


0
Joomla会创建一个包含重写规则的.htaccess文件,以启用搜索引擎友好的URL。如果您使用的是Apache,则需要为包含Joomla安装的目录设置“AllowOverride FileInfo”。如果您使用的是IIS,则需要一个模块,例如IISModRewrite。以下是此操作的说明:[http://www.micronovae.com/ModRewrite/articles/SEFJoomla.html]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接