在32位操作系统中,ip2long返回有符号的int,而在64位操作系统中,返回无符号的int。我的应用程序是工作在10台服务器上,有些是32位,有些是64位,所以我需要所有的工作方式相同。在PHP文档中,有一个技巧可以使结果总是无符号的,但是因为我的数据库已经充满了数据,所以我想让它签名。如何在PHP中将unsigned int转换为signed int?
ip2long
w8ntj3qf1#
PHP不支持unsigned integers作为类型,但你可以做的是简单地将ip2long的结果转换为unsigned int string,方法是让sprintf使用%u将值解释为unsigned:
%u
$ip="128.1.2.3"; $signed=ip2long($ip); // -2147417597 in this example $unsigned=sprintf("%u", $signed); // 2147549699 in this example
编辑,因为你真的希望它即使在64位系统上也是有符号的-下面是如何将64位+ve值转换为32位有符号的等价值:
$ip = ip2long($ip); if (PHP_INT_SIZE == 8) { if ($ip>0x7FFFFFFF) { $ip-=0x100000000; } }
ajsxfq5m2#
Fwiw,如果你使用MySQL,如果你只是将IP作为字符串传递给数据库,让MySQL使用INET_ATON()(当INSERT/UPDAT(E)'ing时)和INET_NTOA()(当SELECTing时)进行转换,通常会更容易和更干净。MySQL不存在这里描述的任何问题。示例:
SELECT INET_NTOA(ip_column) FROM t; INSERT INTO t (ip_column) VALUES (INET_ATON('10.0.0.1'));
查询的可读性也更强。请注意,您不能混合MySQL中的INET_NTOA()/INET_ATON()和PHP中的ip 2long()/long 2 ip(),因为MySQL使用INT UNSIGNED数据类型,而PHP使用有符号**整数。混合使用有符号和无符号整数会严重扰乱你的数据!
zhte4eai3#
在32位和64位系统上将整数值解释为有符号int:
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; }
kgsdhlau4#
$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; }
在64位系统上,打印这个值($ip_int)将显示一个“无符号”整数,因为我们已经删除了高位。但是,这应该允许您按照自己的意愿获取输出并存储它。
sg24os4d5#
public function unsigned2signed($num) { // converts unsigned integer to signed $res = pack('i',$num); // change to 'l' to handle longs $res = unpack('i',$res)[1]; return $res; }
ds97pgxw6#
unsigned-int是一个php库,用于将有符号整数转换为无符号整数。(免责声明:我是作者)
unsigned-int
use Oct8pus\Unsigned\UInt32; require_once './vendor/autoload.php'; $uint32 = new UInt32(-2147483648); echo $uint32;
-2147483648 > 0x80000000 (2147483648)
仓库在这里https://github.com/8ctopus/unsigned-int
2wnc66cl7#
静态转换为32位有符号整数。适用于64位和32位PHP。
function toSInt32($a) { return ~0x7FFFFFFF * (($a >> 31) & 1) + ($a & 0x7FFFFFFF); } -------- var_dump(toSInt32(0)); var_dump(toSInt32(1)); var_dump(toSInt32(0x7FFFFFFF)); var_dump(toSInt32(0x80000000)); var_dump(toSInt32(0x8000000000)); var_dump(toSInt32(0xFFFFFFFF)); var_dump(toSInt32(0xFFFFFFFFFF)); -------- int(0) int(1) int(2147483647) int(-2147483648) int(0) int(-1) int(-1)
7条答案
按热度按时间w8ntj3qf1#
PHP不支持unsigned integers作为类型,但你可以做的是简单地将ip2long的结果转换为unsigned int string,方法是让sprintf使用
%u
将值解释为unsigned:编辑,因为你真的希望它即使在64位系统上也是有符号的-下面是如何将64位+ve值转换为32位有符号的等价值:
ajsxfq5m2#
Fwiw,如果你使用MySQL,如果你只是将IP作为字符串传递给数据库,让MySQL使用INET_ATON()(当INSERT/UPDAT(E)'ing时)和INET_NTOA()(当SELECTing时)进行转换,通常会更容易和更干净。MySQL不存在这里描述的任何问题。
示例:
查询的可读性也更强。
请注意,您不能混合MySQL中的INET_NTOA()/INET_ATON()和PHP中的ip 2long()/long 2 ip(),因为MySQL使用INT UNSIGNED数据类型,而PHP使用有符号**整数。混合使用有符号和无符号整数会严重扰乱你的数据!
zhte4eai3#
在32位和64位系统上将整数值解释为有符号int:
kgsdhlau4#
64位无符号整数在PHP5中不受技术支持。它将使用本机类型。要从64位有符号整型转换为32位有符号整型而不丢失高位,您可以掩码然后键入强制转换输出:
在64位系统上,打印这个值($ip_int)将显示一个“无符号”整数,因为我们已经删除了高位。但是,这应该允许您按照自己的意愿获取输出并存储它。
sg24os4d5#
ds97pgxw6#
unsigned-int
是一个php库,用于将有符号整数转换为无符号整数。(免责声明:我是作者)仓库在这里https://github.com/8ctopus/unsigned-int
2wnc66cl7#
静态转换为32位有符号整数。适用于64位和32位PHP。