2015-06-02 13 views
5

Wie in der PHP-Dokumentation erwähnt, werden sie in floats umgewandelt, wenn eine Datenstruktur mit langen Ganzzahlen in eine json_decode umgewandelt wird. Die Problemumgehung besteht darin, JSON_BIGINT_AS_STRING zu verwenden, die sie stattdessen als Zeichenfolgen erhält. Wenn json_encode solche Werte ing, JSON_NUMERIC_CHECK wird diese Zahlen wieder in große ganzen Zahlen kodieren:json_decode AND json_encode lange ganze Zahlen ohne Daten zu verlieren

$json = '{"foo":283675428357628352}'; 
$obj = json_decode($json, false, JSON_BIGINT_AS_STRING); 
$json2 = json_encode($obj, JSON_NUMERIC_CHECK); 
var_dump($json === $json2); // true 

diese Methode für einen korrekten Umlauf der Daten ist fehleranfällig. Wenn eine Eigenschaft '123' enthält, eine numerische Zeichenfolge, die eine Zeichenfolge bleiben soll, wird sie in eine ganze Zahl codiert.

Ich möchte ein Objekt vom Server abrufen, eine Eigenschaft ändern und dann die gesamte Datenstruktur zurückgeben. Ich muss die ursprünglichen Typen bewahren. Ich möchte keine anderen Eigenschaften beibehalten als die, die ich manipuliere.

Gibt es eine echte Problemumgehung dafür? PHP hat keine Probleme mehr mit großen Ints, aber die json_decode Routine scheint veraltet zu sein.

+1

Haben Sie den ähnlichen Thread überprüft http://StackOverflow.com/Questions/15659325/JSON-Bigint-AS-String-backporting –

+0

Es ist etwas verwirrend, was Sie fragen. Zusammenfassend: Sie wollen 'json_decode' einen Datensatz ändern, eine Eigenschaft ändern, dann' json_encode' es erneut; Ihr Problem besteht darin, dass große ganze Zahlen entweder in Floats oder Strings umgewandelt werden. Habe ich das richtig verstanden? – deceze

+0

Ja, aber der Vorschlag ist, eine Drittanbieter-Lib zu verwenden. Ich mag es, meine Anwendungen klein zu halten. – SuperNova

Antwort

3

Solange Ihre PHP-Version tatsächlich große ganze Zahlen umgehen kann, was bedeutet, wenn Sie eine 64-Bit-Version von PHP (auf etwas other than Windows) laufen lassen, json_decode hat kein Problem mit ihm:

$json = '{"foo":9223372036854775807}'; 
$obj = json_decode($json); 
$json2 = json_encode($obj); 

var_dump(PHP_INT_MAX, $obj, $json2); 

int(9223372036854775807) 
object(stdClass)#1 (1) { 
    ["foo"]=> 
    int(9223372036854775807) 
} 
string(27) "{"foo":9223372036854775807}" 

Wenn die Integer-Werte, die Sie behandeln müssen, PHP PHP_INT_MAX überschreiten, können Sie einfach können nicht sie in nativen PHP-Typen darstellen. Also gibt es keinen Weg um das Rätsel herum, das du hast; Sie können native Typen nicht verwenden, um den richtigen Typ zu verfolgen, und Sie können keine anderen Typen (z. B. Zeichenfolgen anstelle von Ganzzahlen) ersetzen, da dies bei der Codierung zurück zu JSON mehrdeutig ist.

In diesem Fall müssen Sie Ihren eigenen Mechanismus der Verfolgung der richtigen Typen für jede Eigenschaft erfinden und solche Serialisierung mit einem benutzerdefinierten Encoder/Decoder behandeln. Beispielsweise müssten Sie einen benutzerdefinierten JSON-Decoder schreiben, der eine benutzerdefinierte Klasse wie new JsonInteger('9223372036854775808') dekodieren kann, und Ihr benutzerdefinierter Encoder würde diesen Typ erkennen und in einen JSON 9223372036854775808-Wert codieren.

Es gibt keine solche Sache in PHP eingebaut.

+0

Ich benutze Windows 8.1 (64 Bit), Apache v2.4 (64 Bit) und php v5.6.9 (64 Bit). – SuperNova

+2

Nun, Vorbehalt: [* "64-Bit-Plattformen haben normalerweise einen maximalen Wert von etwa 9E18, außer Windows, das ist immer 32 Bit." *] (Http://php.net/manual/en/language.types .integer.php) – deceze

+0

Uhm, ich denke es gibt keine Lösung. Aber ich möchte, dass Sie sich den Ruf verdienen. Vielen Dank. Mein Produktionssystem verwendet Linux und es ist in Ordnung. – SuperNova

Verwandte Themen