PHP中32到64位的“Gotchas”

时间:2008-12-29 13:48:24

标签: php 32bit-64bit

上周末我改变了网站的webhosts。我所使用的主机服务器是32位操作系统,我移动的主机服务器是64位操作系统。出乎意料的是,我的一些PHP脚本开始提供不正确的结果。

在我的情况下<<和>> (位移)操作是罪魁祸首。我最终不得不用0xFFFFFFFF掩盖结果,然后改变结果,如果它为负,它就像以前一样工作。

我的PHP脚本中是否还有其他可能出现的问题?

6 个答案:

答案 0 :(得分:6)

这是一种高级语言,所以任何非位相关的(位运算符,位移)都是相同的。

答案 1 :(得分:4)

整数可以是64位而不是32位。有一些奇怪的cases,这可能会导致问题。

答案 2 :(得分:2)

位操作需要特别小心,以便在系统/体系结构之间进行移植。

在C中,<<和>>通过使用 unsigned 变量可以使操作变得可移植,这会删除负数的1 / twos赞美规则。

作为一般规则,不要使用固定长度的掩码进行位操作(如&和|)。这些都取决于架构。

  

EG。重置最后4位:   掩码0xF0将工作在8位   架构,但不是16位。结果将是不同的(16位可能具有未设置在掩码中的其他位)。

     

要解决此问题,请使用〜运算符。掩码~0xF等效于0xF0,但可以在任何架构上工作。除最后4位之外的所有位都将被重置

答案 3 :(得分:2)

strtotime在64位上表现不同。来自PHP.net:

注意:

时间戳的有效范围通常是从星期五,1901年12月13日20:45:54 UTC到星期二,2038年1月19日03:14:07 UTC。 (这些是与32位有符号整数的最小值和最大值相对应的日期。)此外,并非所有平台都支持负时间戳,因此您的日期范围可能不会早于Unix时期。这意味着,例如1970年1月1日之前的日期不适用于Windows,某些Linux发行版和一些其他操作系统。 PHP 5.1.0和更新的版本克服了这个限制。

对于64位版本的PHP,时间戳的有效范围实际上是无限的,因为64位可以代表任何方向上大约2930亿年。

我们的代码正在执行strtotime('0000-00-00'),并且预期结果为false,当我们移动到64位时,我们得到了一个负整数。

答案 4 :(得分:1)

当您依赖32位二进制数据表示时,您将看到的唯一问题。 主要是因为PHP使用有符号整数,你会看到哈希,密钥生成等问题...当用(int),数字>显式地转换为int时除非它们是> 2,否则2 ^ 32将包裹它们将不会在64位环境中包裹的位置。当然是2 ^ 64。

4 vs 8 bit示例:

十进制值问题:

     0010 >> 1 =      0001   [ 1 dec ]
0000 0010 >> 1 = 0000 0001   [ 1 dec ]

这两个产生相同的结果(十进制),但是:

     0100 << 1 =      1000   [ -8 dec ]
0000 0100 << 1 = 0000 1000   [ 16 dec ]

包装问题:

     1000 << 1 =      0000   [  0 dec ]
0000 1000 << 1 = 0001 0000   [ 32 dec ]

所有整数/浮点运算将被视为64位值,因此如果您的最终结果依赖于32位块,则必须对此进行补偿。

答案 5 :(得分:0)

浮点除法的结果将受到增加到64位的影响;因此,如果您的代码执行某些愚蠢的操作,例如将浮点除法的结果与硬编码常量进行比较,那么期望它会中断。