2015-07-13 4 views
1

У меня есть странное поведение с функцией распаковки. У меня есть упакованная строка, хранящаяся как longblob в базе данных mysql. Когда я читаю эту строку и распаковываю ее, она дает мне массив, настолько хороший. Но когда я запускаю это на другой машине, некоторые из значений в массиве отличаются.Unpack() предоставляет различные результаты на разных машинах

Когда я выгружаю данные из 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 (на одном, что это нормально, на другой нет)

+2

ли одна машина работает 32-разрядное PHP и другой работает 64-разрядное PHP? –

+1

не уверен в этом, uname -a приносит мне «x86_64» на обеих машинах. Будет ли способ, если один из них 32, другой - 64? – Ben

+0

'echo PHP_INT_SIZE * 8;' – AbraCadaver

ответ

3

Формат Npack означает беззнаковое долго , что означает, что он не может быть отрицательным. Тем не менее, вы храните отрицательные значения, и это те, которые не распаковываются так, как вы хотите. 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); 
+0

Спасибо! Я проверю это, как только у меня снова появится доступ к машине! – Ben

+0

Люблю вас всех, сейчас работает. Огромное спасибо. – Ben

Смежные вопросы