解决:LNMP架构下访问php页面出现500错误

如今LNMP架构很流行,php

然而有时咱们会遇到一个莫名其妙的问题,nginx

就是咱们访问php页面时服务器返回"HTTP/1.1 500 Internal Server Error"错误web

这个错误让人匪夷所思,还觉得是nginx出问题了呢?chrome

实际上是php代码语法错误致使的api

默认状况下,若是被访问的php脚本中包含语法错误,服务器会返回一个空的“200 ok”页面安全

在php.ini中的fastcgi.error_header选项容许在这种状况下产生一个HTTP错误码服务器

以使web服务器能够正确拦截并处理这个错误码,相似直接在php代码中调用header()返回500状态码,如cookie

header("HTTP/1.1 500 Internal Server Error");session

经过php源码也能够看出来,本次使用的php版本是:php-5.3.26架构

源文件是:php-5.3.26/main/main.c

第1110行,以下:

if(!PG(display_errors) && !SG(headers_sent) && SG(sapi_headers).http_response_code == 200){
sapi_header_line ctr = {0};
ctr.line = "HTTP/1.0 500 Internal Server Error";
ctr.line_len = strlen(ctr.line);
sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
}

经过if条件能够得知,在知足 display_errors=0 和 headers_sent=0即空白页和

http_response_code=200的条件下返回500错误


初看这个500错误容易误认为nginx出错,能够适当调整为其它响应码

只要在php.ini中设置 fastcgi.error_header 选项便可,如返回503:

fastcgi.error_header = "HTTP/1.1 503 PHP Parse Error"

这样就能够显示出错误的根本缘由,能够在部署LNMP时加上


没加这个选项时,能够经过下面方法调试:

将访问出错的页面拷贝一个,成测试文件,防止影响线上业务和安全问题

如:cp index.php index.test.php

打开 display_errors 选项,在文件开头加入以下内容:

ini_set('display_errors','1');
error_reporting(E_ALL);

这样就能够将错误暴露出来,完毕!


前几天就遇到了这个500错误问题,状况是这样的:

有开发人员说网站访问出现500错误,他说ie和chrome都访问不了,只有firefox能够访问,我本身也试了试,ie和chrome确实不能访问,我机器没装firefox,因此没试,我忽然想起之前公司也遇到过这个问题,因此想到了cookie的问题,就上服务器上排查php程序代码,最后发现这么一段代码:

protected function __construct($domain){
    ...
    session_name(self::sess_name);
    $this->sess_id = empty($_COOKIE[session_name()]) ? $this->gen_sid() : $_COOKIE[session_name()];
    ...
}
private function gen_sid(){
    return md5(uniqid(microtime() . getClientIP(), true));
}

当程序执行到第9行的时候就会发生500错误,最大的可能就是 getClientIP 函数致使的,直接调用这个函数仍然返回500错误,用var_dump(function_exists('getClientIP'))调试,输出false,问题就在这里了,定义好这个函数就解决了。但是为何firefox能够访问,而ie和chrome不能访问呢?这是由于firefox里面存在cookie了,而ie和chrome都是第一次访问,没有cookie,那为何没有cookie就会出现这个问题呢?这要归责于:

$this->sess_id = empty($_COOKIE[session_name()]) ? $this->gen_sid() : $_COOKIE[session_name()];

第一次访问没有cookie,因此empty($_COOKIE[session_name()])为true,

就会调用$this->gen_sid(),就会出现上面找不到getClientIP函数的错误,而cookie存在的话就不会调用$this->gen_sid(),而是返回冒号后面的$_COOKIE[session_name()],就没问题了,呵呵!其实这么排查有点啰嗦,直接打开错误报告,错误就会显现出来,如:

ini_set('display_errors','1');
error_reporting(E_ALL);

显示以下错误信息,很容易就发现问题了,good

Fatal error: Call to undefined function getClientIP()


另外在 php-fpm.conf 中设置的php.ini选项优先于在php.ini中设置的选项,如

在 php.ini 中设置 display_errors = on

在 php-fpm.conf 中设置 php_flag[display_errors] = off

那么结果是 off

相关文章
相关标签/搜索