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

时间:2015-07-13 18:14:52

标签: php unpack

我对unpack函数有一些奇怪的行为。我有一个打包的字符串,在mysql数据库中存储为longblob。当我读取该字符串并将其解压缩时,它给了我一个数组,到目前为止一切都很好。但是当我在另一台机器上运行它时,数组中的一些值是不同的。

当我从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
...
)

每一秒的价值似乎都不同。

我已经在三台不同的机器上测试了这一点,其中一切都很好,但是在那台机器上我得到了那个奇怪的输出。

一台机器正在运行PHP 5.6.3(这里没关系),两台机器正在运行PHP 5.5.14(一台机器正常运行,另一台机器运行正常)

1 个答案:

答案 0 :(得分:3)

pack格式N表示无符号长,这意味着它不能为负数。但是,您存储负值,并且它们不是按照您希望的方式解压缩的值。对于与机器无关的签名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);