Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php中gethostbyaddr()函数的超时问题_Php - Fatal编程技术网

php中gethostbyaddr()函数的超时问题

php中gethostbyaddr()函数的超时问题,php,Php,最近我注意到,在我的新服务器上,我的站点上使用了gethostbyaddr()函数来获取referes的主机,它使页面加载速度慢了5倍 当我移除它时,超时问题就消失了 此函数和我的新Centos linux服务器配置有什么问题 还有什么可以代替这个php函数来获取我的推荐人的主机名。这可能是DNS解析的暂时缓慢,以后可能会自行清除。除了从PHP中进行如下系统调用之外,实在没有任何方法可以替代gethostbyaddr()。(gethostbyaddr()基本上就是这样做的) 您可以使用以下命令行

最近我注意到,在我的新服务器上,我的站点上使用了
gethostbyaddr()
函数来获取referes的主机,它使页面加载速度慢了5倍

当我移除它时,超时问题就消失了

此函数和我的新Centos linux服务器配置有什么问题


还有什么可以代替这个php函数来获取我的推荐人的主机名。

这可能是DNS解析的暂时缓慢,以后可能会自行清除。除了从PHP中进行如下系统调用之外,实在没有任何方法可以替代
gethostbyaddr()
。(
gethostbyaddr()
基本上就是这样做的)

您可以使用以下命令行测试分辨率是否较慢:

# choose an IP address you know the resolution of...
$ host 123.123.123.123
如果这不能很快返回,您可能会遇到DNS问题


检查
/etc/resolv.conf
的内容,如果您有备用DNS服务器,您可以将其指向该服务器,试试该服务器。

您有什么类型的web主机?共享、VPS或专用
gethostbyaddr()
性能取决于web服务器DNS解析的有效性。有些情况可能会降低其性能,但您仍然需要至少说明您使用的主机类型。

我认为您应该为gethostbyaddr()结果实现某种类型的缓存系统(嗯,大多数DNS服务器都有内置的缓存系统,但您的主机可能会因某些原因出现故障)或者尝试使用其他DNS服务器(使用系统调用或更好的PHP套接字)。

我为gethostbyaddr()编写了这个有用的替代品:

诀窍是使用主机功能,但您必须检查$ip是否是真正的ip,以避免攻击。 我把计时器设为1秒


它比使用gethostbyaddr快得多,尽管在循环中使用时速度仍然很慢。

不幸的是,某些isp不维护某些ip地址的反向dns记录,因此dns查找总是会失败。问题是要等多久才能放弃

一些主机服务将gethostbyaddr函数超时设置为实短,如果查找不成功,则ip地址将替换为主机名。这会加快速度,防止在显示调用此函数的页面时出现长时间延迟


您应该始终仔细检查不显示主机名的日志条目,因为它们经常表明访问者来自一个ip地址,该ip地址具有恶意互联网活动的声誉。

从XP升级到7后,它影响了PHP对IPv4和IPv6的处理(例如,127.0.0.1返回为::1)我已经修改了一些代码来暂时解决这个问题。原来我在IPv6补丁上使用了
gethostbyaddr
,因此它在PHP上的计时被卡住了

以前

$ip = ip2long6($ip);
$host = gethostbyaddr($ip);

$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
您可以使用Xdebug和WinCacheGrind(我使用XAMPP进行本地测试)来查找超时的原因,下面是一个视频教程,可以快速浏览

希望这能让某人保持理智。:-)

As不支持超时,我的主机设置不允许shell命令。我决定使用本地API:

<?php
$ip = isset($_GET['ip']) ? filter_var($_GET['ip'], FILTER_VALIDATE_IP) : false;
if ($ip) {
    echo json_encode(gethostbyaddr($ip));
}
?>
正如你所看到的,我设置了超时

样本输出:

IP: 56.152.200.204
HOST: Timeout!
Execution Time: 801 ms

IP: 81.139.131.130
HOST: host81-139-131-130.range81-139.btcentralplus.com
Execution Time: 52 ms
我不知道为什么,但在我的设置中,
0.4
超时在>800毫秒后开始,因此我需要将该值加倍以获得最终超时。也许其他人可以对此发表评论

警告

这将在服务器上为主脚本上的每个请求创建一个额外的http请求

+1用于提及(即,告诉我)主机命令。@Pete主机的
-x
标志不正确。我把它与
dig-x
混淆了。仅使用
host
而不使用任何标志将返回IP的主机名。请提供有用的解决方案,而不要因为人们缺乏理解而责备他们。请使用“host-W 1”命令。我曾经遇到过这样的情况,它经常挂起,即使它不应该使用-w1选项。解决方案很简单:在命令前面加上“timeout”命令,并在那里指定超时。
<?php
$ip = isset($_GET['ip']) ? filter_var($_GET['ip'], FILTER_VALIDATE_IP) : false;
if ($ip) {
    echo json_encode(gethostbyaddr($ip));
}
?>
<?php
// prepare host url
function isSecure() {
    return ((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) ? 's' : '';
}
$protocol_host = 'http' . isSecure() . '://' . filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL);
// dns request
$context = stream_context_create(array(
    'http' => array(
        'timeout' => 0.4,// 400 ms
    )
));
$ip = long2ip(mt_rand(0, "4294967295"));
// note: the host url needs public access!
$host = json_decode(@file_get_contents($protocol_host . '/hostAPI.php?ip=' . $ip, false, $context), true);
// output
echo 'IP: ' . $ip . "<br>\n";
echo 'HOST: ' . ($host ? $host : 'Timeout!') . "<br>\n";
echo 'Execution Time: ' . round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"])  * 1000) . ' ms';
?>
IP: 56.152.200.204
HOST: Timeout!
Execution Time: 801 ms

IP: 81.139.131.130
HOST: host81-139-131-130.range81-139.btcentralplus.com
Execution Time: 52 ms