未签名的 int 以在 php 中签名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/872424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unsigned int to signed in php
提问by Thinker
It appears, that in 32bit OS ip2longreturns signed int, and in 64bit OS unsigned int is returned.
看来,在 32 位操作系统中ip2long返回有符号整数,而在 64 位操作系统中返回无符号整数。
My application is working on 10 servers, and some are 32bit and some are 64bit, so I need all them to work same way.
我的应用程序在 10 台服务器上运行,有些是 32 位的,有些是 64 位的,所以我需要它们都以相同的方式工作。
In PHP documentation there is a trick to make that result always unsigned, but since I got my database already full of data, I want to have it signed.
在 PHP 文档中,有一个技巧可以使该结果始终未签名,但是由于我的数据库已经充满数据,因此我希望对其进行签名。
So how to change an unsigned int into a signed one in PHP?
那么如何在 PHP 中将无符号整数更改为有符号整数呢?
回答by Paul Dixon
PHP does not support unsigned integers as a type, but what you can do is simply turn the result of ip2longinto an unsigned int stringby having sprintfinterpret the value as unsigned with %u:
PHP 不支持无符号整数作为类型,但您可以做的只是通过让sprintf将值解释为无符号,将ip2long的结果转换为无符号整数字符串:%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:
编辑,因为你真的希望它甚至在 64 位系统上签名 - 以下是你如何将 64 位 +ve 值转换为 32 位签名等价物:
$ip = ip2long($ip);
if (PHP_INT_SIZE == 8)
{
if ($ip>0x7FFFFFFF)
{
$ip-=0x100000000;
}
}
回答by Wouter Bolsterlee
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.
Fwiw,如果您使用 MySQL,如果您只是将 IP 作为字符串传递给数据库,并让 MySQL 使用 INET_ATON()(当 INSERTing/UPDAT(E)'ing 时)和INET_NTOA()(选择时)。MySQL 没有这里描述的任何问题。
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 notmix INET_NTOA()/INET_ATON() in MySQL with ip2long()/long2ip() in PHP, since MySQL uses an INT UNSIGNED datatype, while PHP uses a signedinteger. Mixing signed and unsigned integers will seriously mess up your data!
请注意,您不能将 MySQL 中的 INET_NTOA()/INET_ATON() 与 PHP 中的 ip2long()/long2ip() 混合使用,因为 MySQL 使用 INT UNSIGNED 数据类型,而 PHP 使用有符号整数。混合有符号和无符号整数会严重弄乱您的数据!
回答by epos_jk
interpreting an integer value as signed int on 32 and 64 bit systems:
在 32 位和 64 位系统上将整数值解释为有符号整数:
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;
}
回答by cyberbill
-Misunderstood problem, see Paul Dixon's answer above.
- 被误解的问题,请参阅上面 Paul Dixon 的回答。
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:
PHP5 在技术上不支持 64 位无符号整数。它将使用本机类型。要在不丢失高位的情况下从 64 位有符号整数转换为 32 位有符号整数,您可以屏蔽然后键入输出:
$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.
在 64 位系统上,打印此值 ($ip_int) 将显示一个“无符号”整数,因为我们已经删除了高位。但是,这应该允许您获取输出并按照您的意愿存储它。

