Unpack() 在不同的机器上提供不同的结果

Unpack() delivers different results on different machines

我的解包功能有一些奇怪的行为。我有一个压缩字符串,作为 longblob 存储在 mysql 数据库中。当我读取该字符串并将其解压缩时,它会为我提供一个数组,到目前为止一切顺利。但是当我在另一台机器上 运行 时,数组中的一些值是不同的。

当我转储来自 mysql 的数据时,它们在两台机器上是相同的。

解包是这样完成的:

$array = unpack("N*", $packed); 

$array 应该是这样的(并且在一台机器上)

Array
(
    [1]  => 179848175
    [2]  => -16214255
    [3]  => 179848175
    [4]  => -16214255
    [5]  => 179848175
    [6]  => -16214255
    [7]  => 179999949
    [8]  => -16152916
    [9]  => 179999277
    [10] => -16168574
...
)

但是在另一台机器上是这样的:

Array
(
    [1]  => 179848175
    [2]  => 427853622
    [3]  => 179848175
    [4]  => 427853622
    [5]  => 179848175
    [6]  => 427853622
    [7]  => 179999949
    [8]  => 427853423
    [9]  => 179999277
    [10] => 427853341
...
)

每一秒的值似乎都不一样。

我已经在三台不同的机器上对此进行了测试,在两台机器上一切正常,但在那一台机器上我得到了奇怪的输出。

一台机器是运行ning PHP 5.6.3(这里可以),两台机器是运行ning PHP 5.5.14(就一个吧可以,另一方面不行)

pack格式N表示unsigned long,也就是说不能为负数。但是,您存储的是负值,而这些负值并未按照您希望的方式解包。 PHP 没有 pack 机器无关的有符号长整数格式;它只支持按机器字节顺序打包它们,这可能在机器之间不兼容。因此,您必须自己对值进行签名。

要将您的数组项转换为有符号值:

for ($i = 1; $i <= count($array); $i++) {
    // Check for a greater-than-32-bit environment,
    // and check if the number should be negative
    // (i.e., if the high bit is set in 32-bit notation).
    if (PHP_INT_SIZE > 4 && $array[$i] & 0x80000000) {
        // A negative number was unpacked as an unsigned
        // long in a greater-than-32-bit environment.
        // Subtract the appropriate amount (max 32-bit
        // unsigned long + 1) to convert it to negative.
        $array[$i] = $array[$i] - 0x100000000;
    }
}

var_dump($array);