2015-10-06 23 views
6

Natknąłem się na dziwny błąd/problem.PHP losowo zmniejsza liczbę całkowitą o 1

Mam tabelę MySQL z kolumną wypełnioną liczbami (BIGINT). Liczby te są zbyt duże dla zwykłej 32-bitowej liczby całkowitej, więc PHP będzie je przesyłać do ciągu 32-bitowego. Daje to prawidłowy wynik za każdym razem.

Kiedy uruchomić na 64-bitowych PHP i nie przymusowo oddane do łańcucha z $variable = (string)$variable, wynik będzie czasami być zmniejszana o 1, tak, że liczba jak 1293203059233 staje 1293203059232. To oczywiście nie jest dobre. Dziwne jest to, że nie widzę żadnego wzoru.

To nie zdarza się przypadkowo, tak że jeden wiersz z MySQL jest zmniejszany czasami, a czasami nie, ale tak, że sama całkowitymi/wiersze są zawsze zmniejszane, a zawsze o 1.

Co może być przyczyną tego? Używam json_encode do konwersji stdClass -obiekty lub arrays() na tekst, a następnie wysłać je za pomocą zwykłych odpowiedzi HTTP.

Wiersze są pobierane przez mysqli użyciem przygotowanych sprawozdań, takich jak:

$stmt = $sql->prepare->("SELECT BIGNUMBER FROM table WHERE SOMEID = ?"); 
$stmt->bind_result($bignumber); 
$stmt->bind_param("i",$someid); 
$stmt->execute(); 
$stmt->fetch(); 
$stmt->close(); 

$obj = new stdClass(); 
$obj->number = $bignumber; 

echo json_encode($obj); 

I sprawdzeniu, że wszystkie liczby całkowite są prawidłowe podczas przeglądania tabeli bazy danych.

Niektóre przykłady (są to wartości rzeczywiste):

bez obsady do wyrażenie:

10205160559939609 -> 10205160669939608 // bad 

z:

10205160559939609 -> "10205160559939609" // good 

bez obsady do wyrażenie:

10154493437278508 -> 10154493437278508 // good (?) 

wi th:

10154493437278508 -> "10154493437278508" // good 

EDIT: Zrobiłem error_log wstępnego testu json_encode do przetestowania, otrzymując:

as Strng: (used error_log((string)$number);) 
10205160559939609 
as int: (used error_log($number);) 
10205160559939609 

co wskazywałoby, że PHP nie uzyskać prawidłową wartość, i że błąd pojawia się w obu php json_encode lub w metodzie dekodowania przeglądarki.

+0

Czy możesz śledzić i wyświetlać liczby, czy ktoś może rozpoznać wzór? – Styphon

+2

Proszę zobaczyć tę odpowiedź http://stackoverflow.com/a/9622041/1866988 –

+0

Dodano kilka przykładów – nickdnk

Odpowiedz

2

Po prostu wpisując 10205150669939609 w chromowanej konsoli otrzymasz wydrukowany numer 10205150669939608 (efekt zaokrąglenia). Sądzę, że liczby całkowite tak duże nie są poprawne w JS, więc nie powinny być w JSON. Gdybym miał tak duże wartości, użyłbym ciągów.

+0

ze wszystkich dyskusji w komentarzach Mam nadzieję, że ta odpowiedź byłaby trochę, no, bardziej edukacyjna. – Martin

+0

, takie jak wyjaśnienie, że problem nie dotyczy samego PHP, ponieważ wartość PHP_INT_MAX jest większa niż użyta int, i że problemem jest specyficzna enkapsulacja JSON', ponieważ javascript uważa wszystkie liczby za zmienne, a nie liczby całkowite. Jest to więc błąd zaokrąglania, gdy zmienna float (DOUBLE) jest ponownie w PHP typu INT. – Martin

+0

@Martin - "powrócił do istnienia typu INT w PHP.". Masz na myśli "w JavaScript"? PHP nie ma żadnych problemów z moimi numerami. – nickdnk

Powiązane problemy