Unsigned int to signed in php

后端 未结 4 1113
别跟我提以往
别跟我提以往 2021-01-06 00:43

It appears, that in 32bit OS ip2long returns signed int, and in 64bit OS unsigned int is returned.

My application is working on 10 servers, and some are

相关标签:
4条回答
  • 2021-01-06 00:46

    PHP does not support unsigned integers as a type, but what you can do is simply turn the result of ip2long into an unsigned int string by having sprintf interpret the value as unsigned with %u:

     $ip="128.1.2.3";
     $signed=ip2long($ip);             // -2147417597 in this example
     $unsigned=sprintf("%u", $signed); //  2147549699 in this example
    

    Edit, since you really wanted it to be signed even on 64 bit systems - here's how you'd convert the 64 bit +ve value to a 32 bit signed equivalent:

    $ip = ip2long($ip);
    if (PHP_INT_SIZE == 8)
    {
        if ($ip>0x7FFFFFFF)
        {
            $ip-=0x100000000;
        }
    }
    
    0 讨论(0)
  • 2021-01-06 00:56

    -Misunderstood problem, see Paul Dixon's answer above.


    64bit unsigned integers are not technically supported in PHP5. It will use the native type. To convert to a 32bit signed int from a 64bit signed int without losing the high bit, you could mask and then type cast the output:

    $ip_int = ip2long($ip);
    if (PHP_INT_SIZE == 8) // 64bit native
    {
      $temp_int = (int)(0x7FFFFFFF & $ip_int);
      $temp_int |= (int)(0x80000000 & ($ip_int >> 32));
      $ip_int = $temp_int;
    }
    

    On a 64 bit system, printing this value ($ip_int) will display an 'unsigned' integer since we've removed the high bit. However this should allow you to take the output and store it how you wish.

    0 讨论(0)
  • 2021-01-06 00:58

    Fwiw, if you're using MySQL it's usually a lot easier and cleaner if you just pass in the IPs as strings to the database, and let MySQL do the conversion using INET_ATON() (when INSERTing/UPDAT(E)'ing) and INET_NTOA() (when SELECTing). MySQL does not have any of the problems described here.

    Examples:

    SELECT INET_NTOA(ip_column) FROM t;
    
    INSERT INTO t (ip_column) VALUES (INET_ATON('10.0.0.1'));
    

    The queries are also much more readable.

    Note that you can not mix INET_NTOA()/INET_ATON() in MySQL with ip2long()/long2ip() in PHP, since MySQL uses an INT UNSIGNED datatype, while PHP uses a signed integer. Mixing signed and unsigned integers will seriously mess up your data!

    0 讨论(0)
  • 2021-01-06 01:10

    interpreting an integer value as signed int on 32 and 64 bit systems:

    function signedint32($value) {
        $i = (int)$value;
        if (PHP_INT_SIZE > 4)   // e.g. php 64bit
            if($i & 0x80000000) // is negative
                return $i - 0x100000000;
        return $i;
    } 
    
    0 讨论(0)
提交回复
热议问题