为什么fsockopen()传入空IP访问80端口时会返回资源而非FALSE?
问题原因分析
空主机名参数返回资源的原因
- 当你向
fsockopen()传入空字符串、NULL作为主机名参数时,PHP底层网络逻辑会默认将空值解析为本地回环地址127.0.0.1(即localhost) - 如果你的本地环境中80端口(通常对应Web服务)或22端口(通常对应SSH服务)处于开放监听状态,连接会直接成功,因此函数会返回有效套接字资源,和你观察到的现象完全一致。
主机名参数为"123"返回FALSE的原因
- 字符串
123既不是符合规范的IPv4/IPv6地址,也不是可被DNS正常解析的有效域名,PHP在地址解析阶段就会直接报错返回,因此结果为FALSE,和你的预期一致。
适配预期的修正方案
你可以在调用fsockopen()之前先增加主机参数合法性校验,只有参数符合格式要求时再发起端口检测,即可避免空参数误判本地服务的问题,参考实现代码如下:
/** * 校验主机参数是否合法 * @param string $host 待校验的主机地址 * @return bool */ function is_valid_host(string $host): bool { // 校验是否为合法IPv4 if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { return true; } // 校验是否为合法IPv6 if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { return true; } // 校验是否为合法域名 if (filter_var($host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) { return true; } return false; } // 调用示例 $target_host = ''; // 待检测的主机参数 $target_port = 80; if (!is_valid_host($target_host)) { // 参数不合法直接返回失败,符合你的预期 $check_result = false; } else { $conn = fsockopen($target_host, $target_port, $err_code, $err_msg, 1); $check_result = is_resource($conn); if ($check_result) { fclose($conn); } } var_dump($check_result);
内容的提问来源于stack exchange,提问作者spacecraft96
相关产品推荐
相关产品推荐

