V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kn007
V2EX  ›  PHP

[php]gethostbyname 的奇怪问题。。。对数字自动 long2ip

  •  
  •   kn007 · 2015-03-29 12:32:47 +08:00 · 3922 次点击
    这是一个创建于 3503 天前的主题,其中的信息可能已经有所发展或是发生改变。
    示例:
    <?php
    var_dump (gethostbyname('kn007.net'));
    var_dump (gethostbyname('162.250.97.124'));
    var_dump (gethostbyname('123'));
    var_dump (gethostbyname('12.3'));
    var_dump (gethostbyname('1.2.3'));
    var_dump (gethostbyname('256'));
    var_dump (gethostbyname('1234567890'));
    ?>
    输出:
    string(14) "162.250.97.124"
    string(14) "162.250.97.124"
    string(9) "0.0.0.123"
    string(8) "12.0.0.3"
    string(7) "1.2.0.3"
    string(7) "0.0.1.0"
    string(12) "73.150.2.210"
    今天才发现这个问题。。。
    http://kn007.net/ip.php
    起因就是这个ip查询。
    $ip=is_ip($ip_) ? $ip_ : gethostbyname($ip_);
    gethostbyname能不能对数字返回false,或者怎么判断?
    第 1 条附言  ·  2015-03-29 17:17:24 +08:00
    表达没清楚

    ip查询,可以查询域名和ip

    现在就是查询下面这些都能查
    1
    1.1
    1.1.1
    1.1.1.1
    abc.abc
    abc.abc.abc
    abc.abc.abc.abc
    http://abc.abc
    https://abc.abc.abc
    ftp://abc.abc.abc.abc

    想对以下不查询
    1
    1.1
    1.1.1

    目前查询流程:
    第一步,就是格式化输入str。
    第二步,判断非ip,进行gethostbyname后查询数据库,是ip查数据库。

    而gethostbyname会对
    1
    1.1
    1.1.1
    进行处理,使其成为x.x.x.x的真正ip
    第 2 条附言  ·  2015-03-29 17:20:49 +08:00
    补充:现在以
    $ip=is_ip($ip_)?$ip : gethostbyname(pre_gethostbyname($ip_));


    function pre_gethostbyname($str) {
    if(preg_match("/^(?:[0-9]{1,3}\.){0,2}[0-9]{1,3}$/", $str)) {
    return false;
    }
    return $str;
    }

    可以解决。但又有个奇怪的问题。。。

    输入 a0,abc 居然也能查询。。。
    第 3 条附言  ·  2015-03-29 17:49:55 +08:00
    @msg7086 @abelyao 暂时以
    function pre_gethostbyname($str) {
    if(preg_match("/^(?:[0-9]{1,3}\.){0,2}[0-9]{1,3}$/", $str))
    return false;
    if(strpos($str,'.') === false)
    return false;
    return $str;
    }
    解决。。。


    真是奇葩的问题,

    输入 a0,abc 居然也能查询。。。我服了

    <?php
    var_dump(gethostbyname('a0'));
    var_dump(gethostbyname('abc'));
    ?>
    string(13) "81.218.249.12"
    string(15) "162.243.117.188"

    用ping和curl都获取不到,gethostbyname是怎么得到地址的!?

    ping: unknown host a0
    curl: (6) Couldn't resolve host 'a0'
    20 条回复    2015-03-29 21:34:28 +08:00
    abelyao
        1
    abelyao  
       2015-03-29 14:38:33 +08:00 via iPhone
    我开始怀疑楼主是来宣传网站的了…
    上个帖子也一样的套路…
    kn007
        2
    kn007  
    OP
       2015-03-29 15:57:35 +08:00
    @abelyao 但这确实是个问题。
    我不否认其中也有宣传的嫌疑,因为我确实这样做了。
    kn007
        3
    kn007  
    OP
       2015-03-29 16:03:09 +08:00
    @abelyao 因为昨天下午开始整理网站,所以发现了很多问题。我实在不知道这个要怎么弄了。
    刚去ipip.net试了,貌似情况一样。试图google,没发现有用的。
    msg7086
        4
    msg7086  
       2015-03-29 16:11:58 +08:00   ❤️ 1
    不能。数字本来就是合法的IP地址。
    abelyao
        5
    abelyao  
       2015-03-29 16:12:17 +08:00
    @kn007 你举例的那几个,除了最后一个我不理解是为啥之外,其它都很好理解吧,本身就是 IP 地址的一些缩写方式,如果你一定要让纯数字范围 false 的话,可以实现判断一下,用正则或者 is_numeric 之类的函数都行。

    另外可以多看看这一页的许多例子 http://php.net/manual/zh/function.gethostbyname.php
    msg7086
        6
    msg7086  
       2015-03-29 16:23:28 +08:00
    @abelyao 纯数字是IP地址的十进制写法。
    kn007
        7
    kn007  
    OP
       2015-03-29 16:26:21 +08:00
    @abelyao 最后一个?
    is_numeric的话,除了1、1.2,1.2.3或1.2.3.4都是false。
    正则的话,匹配非合法ipv4,自然要gethostbyname,gethostbyname后,不合法的又变为合法了。
    因为输入进来可能是域名也可能是ip,
    判断非ip就gethostbyname,是ip直接查数据库。
    问题非ip经过gethostbyname可能就被合法了。
    kn007
        8
    kn007  
    OP
       2015-03-29 16:46:32 +08:00
    @abelyao 你说的正则的法子,我是真的想了。。
    真不知道怎么破。
    比如ipip.net他们的框不能输入http://www.ipip.net/,无法查询,我的可以,这些都是自己写的。
    现在第一步,就是格式化输入str。
    第二步,判断非ip,进行gethostbyname,是ip查数据库。

    现在就是卡在gethostbyname,会对数字进行格式化(long2ip)。
    13.1在经过第二步,已经变成13.0.0.1了。合法了。
    如果单纯十进制还好,就以is_numeric判断。
    kn007
        9
    kn007  
    OP
       2015-03-29 16:47:37 +08:00
    我刚想了下,只能用个笨办法。
    就是第一步,就是格式化输入str。
    第二步,判断,是ip查数据库,不是继续下一步。
    第三步,explore('.',$str)进行count()<4然后foreach判断is_numeric,如果都过就返回false,不过就gethostbyname。或正则匹配match_all,如果小于4个,就返回false,否则gethostbyname。

    我去试试先
    msg7086
        10
    msg7086  
       2015-03-29 16:51:04 +08:00
    如果可以的话,建议你重新提一下问题。
    你主贴里说怎么判断是数字,那么上面说了is_numeric()。
    能不能说清楚你到底要判断什么?
    iyaozhen
        11
    iyaozhen  
       2015-03-29 16:56:15 +08:00
    不知道楼主要干啥。本身就是正确的呀。
    硬是要判断的话判断下有没有点(.)。
    kn007
        12
    kn007  
    OP
       2015-03-29 17:06:13 +08:00
    @msg7086 就是ip查询,输入进来可能是域名,可能是ip,可能是数字。
    我重新提一下吧。
    kn007
        13
    kn007  
    OP
       2015-03-29 17:07:04 +08:00
    @iyaozhen 判断点有什么用? 1.1、1.1.1、abc.com这些都不有点。。
    kn007
        14
    kn007  
    OP
       2015-03-29 17:34:51 +08:00
    @abelyao

    现在以
    $ip=is_ip($ip_)?$ip : gethostbyname(pre_gethostbyname($ip_));


    function pre_gethostbyname($str) {
    if(preg_match("/^(?:[0-9]{1,3}\.){0,2}[0-9]{1,3}$/", $str)) {
    return false;
    }
    return $str;
    }

    可以解决。但又有个奇怪的问题。。。

    输入 a0,abc 居然也能查询。。。我服了

    <?php
    var_dump(gethostbyname('a0'));
    var_dump(gethostbyname('abc'));
    ?>
    string(13) "81.218.249.12"
    string(15) "162.243.117.188"

    @msg7086 莫非字母也能变成ip。。。26个字母都可以查。。。。
    kn007
        15
    kn007  
    OP
       2015-03-29 17:55:49 +08:00
    已去问鸟哥了。。。感觉不科学。
    msg7086
        16
    msg7086  
       2015-03-29 21:29:55 +08:00 via iPhone
    主机名不带点很正常啊…
    kn007
        17
    kn007  
    OP
       2015-03-29 21:30:46 +08:00
    @msg7086
    msg7086
        18
    msg7086  
       2015-03-29 21:32:47 +08:00 via iPhone
    @kn007 好像会自动补上域后缀的。
    kn007
        19
    kn007  
    OP
       2015-03-29 21:34:07 +08:00
    @msg7086 。。。。这样也行
    kn007
        20
    kn007  
    OP
       2015-03-29 21:34:28 +08:00
    @msg7086 真希望有个flag来限制
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2862 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:19 · PVG 23:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.