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请求就可以了。