Pregunta

Parece que en SO de 32 bits ip2long vuelve firmaron int y en SO de 64 bits se devuelve unsigned int.

Mi aplicación está trabajando en 10 servidores, y algunos son de 32 bits y algunos son de 64 bits, por lo que es necesario que todos ellos trabajan misma manera.

En la documentación de PHP no es un truco para hacer que el resultado siempre sin firmar, pero desde que tengo mi base de datos ya está lleno de datos, yo quiero tener que firmó.

Entonces, ¿cómo cambiar un entero sin signo en una firmado uno en PHP?

¿Fue útil?

Solución

PHP no soporta enteros sin signo como un tipo, pero lo que puede hacer es simplemente gire el resultado de ip2long en un unsigned int cadena sprintf interpretar el valor sin signo con %u:

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

Editar, ya que realmente quería que fuera firmado incluso en sistemas de 64 bits - aquí te mostramos cómo convertir el bit 64 + ve a un valor equivalente con signo de 32 bits:

$ip = ip2long($ip);
if (PHP_INT_SIZE == 8)
{
    if ($ip>0x7FFFFFFF)
    {
        $ip-=0x100000000;
    }
}

Otros consejos

Fwiw, si estás usando MySQL por lo general es mucho más fácil y más limpio si lo que pasa en los proyectos de investigación como cadenas a la base de datos, y dejar que MySQL hacer la conversión usando INET_ATON () (al insertar / updat (E)' ing) y inet_ntoa () (cuando se selecciona). MySQL no tiene ninguno de los problemas que se describen aquí.

Ejemplos:

SELECT INET_NTOA(ip_column) FROM t;

INSERT INTO t (ip_column) VALUES (INET_ATON('10.0.0.1'));

Las consultas son también mucho más fácil de leer.

Tenga en cuenta que puede no mezclar inet_ntoa () / INET_ATON () de MySQL con ip2long () / long2ip () en PHP, ya que MySQL utiliza un tipo de datos UNSIGNED INT, mientras que PHP utiliza un firmado número entero. Mezclar enteros con y sin signo estarán seriamente estropear sus datos!

interpretar un valor entero como int firmado en los sistemas de 32 y 64 bits:

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;
} 

-Misunderstood problema, véase la respuesta de Paul Dixon anteriormente.


enteros de 64 bits sin signo no son compatibles técnicamente en PHP5. Se utilizará el tipo nativo. Para convertir a una de 32 bits firmado int de un int firmado de 64 bits sin perder el bit alto, que podría enmascarar y escriba emitir la salida:

$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;
}

En un sistema de 64 bits, la impresión de este valor ($ ip_int) mostrará un número entero 'sin firmar', ya que hemos eliminado el bit alto. Sin embargo, esto debería permitir que tome la salida y lo almacena como desea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top