fsockopen返回null的怪异问题排查

今天测试过程中发现fsockopen请求有问题,代码里进行了断点记录,具体代码如下:

if(function_exists('fsockopen')) {
	$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
        file_put_contents('d.log', var_export($fp)); // 断点记录
}

执行后,找到d.log文件,内容如下:

null

查了PHP手册里fsockopen函数的说明,如果失败应该是返回false。
呃,居然返回了null,十分怪异。网上搜索了下相关问题,没找到具体原因,但是有发现类似的问题。

没办法,本地重新写了个脚本test.php,具体代码(忽略部分代码):

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);

执行这个脚本,输出结果为:

resource(21) of type (stream)

囧,居然成功了。
好吧,两个的区别是一个是用文件记录的,另一个是直接输出的。

将test.php文件的代码改为如下:

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);
file_put_contents('d.log', var_export($fp, TRUE));

执行后,页面直接输出还是

resource(21) of type (stream)

但是文件里记录的内容却是:

null

好吧,问题就处在var_dump和var_export这两个函数上。
在PHP手册上关于var_export函数的说明里找到下面一句话:

Variables of type resource couldn't be exported by this function.

资源类型的变量不能使用这个函数输出。

var_export() differs from print_r() for variables that are resources, with print_r() being more useful if you are using the function for debugging purposes.

如果是调试目的的话,print_r更为有用。

回到test.php文件,修改为下面的代码:

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);
echo "\n";
var_dump(var_export($fp, TRUE));
echo "\n";
print_r($fp);

执行后,页面的输出为:

resource(14) of type (stream) 
string(4) "NULL" 
Resource id #14

0116更新:
今天又碰到返回为null的情况了。。
接口里不好判断,单独写了个脚本模拟了下,发现fsockopen返回如下信息:

unable to connect to 192.168.0.180:80 (No route to host)

问了下系统的同事,说是这台服务器和要请求的服务器不在一个机房,没法用内网IP。
改成用host请求就可以了。

标签: none

添加新评论