1

次のように、IP cidr または単一の IP の配列を受け入れる以下の関数があります。

$cidrs = array("127.0.0.1","65.87.43.65/32");

等..

次に、関数は、指定された IP がその IP と CIDR の配列でリッスンしているかどうか、CIDR にあるか、指定された単一の IP であるかを確認します。

問題は、IP に CIDR マスクが含まれていない場合、リスト内の IP が何であれ、常に true を返すことです。

少なくとも一度は機能したと確信していますが、動作を変更するために何を変更したかはわかりません。

機能は以下の通りです。

function testIP($user_ip, $cidrs)   
{  
    $ipu = explode('.', $user_ip);  
    foreach ($ipu as &$v)  
        $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT);  

    $ipu = join('', $ipu);  
    $res = false;  

    foreach ($cidrs as $cidr)   
    {  

        $parts = explode('/', $cidr);  

        if (empty($parts))  
        {  
            if (in_array($user_ip, $cidrs))  
            {  
                $res = true;  
                break;  
            } 
            break;         
        }  



        $ipc = explode('.', $parts[0]);  

        foreach ($ipc as &$v) $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT);  

        $ipc = substr(join('', $ipc), 0, $parts[1]);  

        $ipux = substr($ipu, 0, $parts[1]);  
        $res = ($ipc === $ipux);  
        if ($res) break;  
    }  
    return $res;  
}

私は一生、それが機能しなくなった理由を理解することはできません-これで多くの時間を失いました!

4

1 に答える 1

1

explode常に配列を返します。あなたのif (empty(...チェックは失敗しています。if (count($parts)==1)やってみる$res = in_array($user_ip, $cidrs)

編集: また、中断しないで、次のcidrに進みます:

    if (count($parts)==1)
    {  
        if (in_array($user_ip, $cidrs))  
        {  
            $res = true;  
            break;  
        } 
        continue;         
    }  
于 2013-03-23T21:54:55.390 に答える