Fehler "unexpected token: numeric literal" beim Versuch PHP-Array zu übernehmen
Nico R.
- javascript
- json
- php
Hallo zusammen,
ich versuche, ein PHP-Array in ein JS-Objekt zu überführen. Es handelt sich um ein numerisches Array, das in PHP fehlerfrei funktioniert. Aber wenn ich es versuche per
let toreArrayDB = "<?=json_encode($toreArray)?>";
als JS-Objekt zu speichern, bekomme ich in in der Konsole diese Fehlermeldung: Uncaught SyntaxError: unexpected token: numeric literal
So sieht der Variablen-Inhalt im Debugger aus:
let toreArrayDB = "{"0":["347",{"1":["10",null]}],"1":["344",{"1":["20","1"],"2":["30",null]}],"3":["338",{"1":["30",null]}]}";
Das sieht doch eigentlich nach korrektem JSON-Format aus. Oder nicht? Übersehe ich etwas? Warum lässt mich JS das nicht zumindest als String speichern?
Der Vollständigkeit halber hier noch das PHP-Array:
array(3) {
[0]=>
array(2) {
[0]=>
string(3) "347"
[1]=>
array(1) {
[1]=>
array(2) {
[0]=>
string(2) "10"
[1]=>
NULL
}
}
}
[1]=>
array(2) {
[0]=>
string(3) "344"
[1]=>
array(2) {
[1]=>
array(2) {
[0]=>
string(2) "20"
[1]=>
string(1) "1"
}
[2]=>
array(2) {
[0]=>
string(2) "30"
[1]=>
NULL
}
}
}
[3]=>
array(2) {
[0]=>
string(3) "338"
[1]=>
array(1) {
[1]=>
array(2) {
[0]=>
string(2) "30"
[1]=>
NULL
}
}
}
}
Schöne Grüße
Nico
Jetzt, wo ich nochmal draufgestarrt habe, ist mir doch noch ein Licht aufgegangen. Die Kombination aus ="{" ging natürlich nicht. Mit
let toreArrayDB = '<?=json_encode($toreArray)?>';
hats funktioniert.
Gute Nacht ;-)
Hi,
Jetzt, wo ich nochmal draufgestarrt habe, ist mir doch noch ein Licht aufgegangen. Die Kombination aus ="{" ging natürlich nicht. Mit
let toreArrayDB = '<?=json_encode($toreArray)?>';
hats funktioniert.
aber eher zufällig, weil kein ' in den Werten vorkommt.
Escaping ist das Stichwort. Bzw. in deutscher Sprache: Kontextwechsel.
cu,
Andreas a/k/a MudGuard
@@Nico R.
Jetzt, wo ich nochmal draufgestarrt habe, ist mir doch noch ein Licht aufgegangen. Die Kombination aus ="{" ging natürlich nicht. Mit
let toreArrayDB = '<?=json_encode($toreArray)?>';
hats funktioniert.
Ja, wenn du "
außen als Stringbegrenzer verwendest, darf im String natürlich kein nicht-escapetes "
sein. Da ist '
als Stringbegrenzer zu verwenden richtig. Und, wie @MudGuard schon anmerkte, darf dann natürlich kein nicht-escapetes '
im String sein.
(Sollten welche vorkommen, müssten sie entweder als \'
escapet werden oder – wenn es sich um Text handelt – durch richtige Apostrophe ’
ersetzt werden.)
Andersrum außen "
und innen '
würde nicht funktionieren, da das JSON-Format nur "
, aber nicht '
als Stringbegrenzer zulässt.
Warum hast du numerische Werte überhaupt als Strings im JSON? Die Identifier (vor den :
) müssen Strings sein, aber die Werte nach den [
nicht. Das ist auch valides JSON:
{"0":[347,{"1":[10,null]}],"1":[344,{"1":[20,"1"],"2":[30,null]}],"3":[338,{"1":[30,null]}]}
Kwakoni Yiquan
Hallo Gunnar,
Warum hast du numerische Werte überhaupt als Strings im JSON?…
das ist mir gar nicht aufgefallen. Ich hatte die Werte unbehandelt (Asche auf mein Haupt) aus der DB im Array gespeichert. Da die Werte dort als INT gespeichert sind, wäre ich eigentlich davon ausgegangen, dass sie auch als INT "herausgeholt" werden. Offensichtlich ist das nicht der Fall. Es handelt sich noch um ein älteres Script ohne Prepared Statements. Ich behandle die Werte jetzt mit (int) nach.
Gruß Nico
Moin Nico,
Warum hast du numerische Werte überhaupt als Strings im JSON?…
das ist mir gar nicht aufgefallen.
Naja, es ist schon ein Unterschied, ob Dein JSON so …
{"0": "wert1", "1": "zwei" }
… oder so aussieht:
["wert1", "zwei"]
Ich hatte die Werte unbehandelt (Asche auf mein Haupt) aus der DB im Array gespeichert. Da die Werte dort als INT gespeichert sind, wäre ich eigentlich davon ausgegangen, dass sie auch als INT "herausgeholt" werden.
Welchen Typ haben denn die betreffenden Tabellenspalten? Das spielt auch eine Rolle, denn eine '1'
als VARCHAR
ist eben ein String, während eine Spalte des Typs INTEGER
wirklich nur Zahlen enthalten kann.
Offensichtlich ist das nicht der Fall. Es handelt sich noch um ein älteres Script ohne Prepared Statements.
Die Art der Statements hat nichts mit dem Speichern der Daten zu tun.
Viele Grüße
Robert
Hallo Robert,
Welchen Typ haben denn die betreffenden Tabellenspalten? Das spielt auch eine Rolle, denn eine
'1'
alsVARCHAR
ist eben ein String, während eine Spalte des TypsINTEGER
wirklich nur Zahlen enthalten kann.
Es handelt sich um INTs, bzw. um TINYINTs und SMALLINTs.
Naja, es ist schon ein Unterschied, ob Dein JSON so …
{"0": "wert1", "1": "zwei" }
… oder so aussieht:
["wert1", "zwei"]
Ja, das beschäftigt mich auch noch, da ein paar Folgeprobleme aufgetaucht sind. Ich hab offensichtlich noch etwas Nachholbedarf, was den Aufbau von JSON und die Rück-Überführung in ein Array bzw. Objekt angeht.
Ich würde hierzu mal in Kürze einen neuen Beitrag aufmachen. Oder direkt hier? Das ursprüngliche Problem mit dem Kontextwechsel war ja eigentich gelöst.
Schöne Grüße
Nico
Hallo
Ja, das beschäftigt mich auch noch, da ein paar Folgeprobleme aufgetaucht sind. Ich hab offensichtlich noch etwas Nachholbedarf, was den Aufbau von JSON und die Rück-Überführung in ein Array bzw. Objekt angeht.
Ich würde hierzu mal in Kürze einen neuen Beitrag aufmachen. Oder direkt hier? Das ursprüngliche Problem mit dem Kontextwechsel war ja eigentich gelöst.
Mache für jeweils ein abgrenzbares Problem auch jeweils einen eigenen Thread auf. Bei zusammenhängenden Problemen kannst du natürlich auch in einem Thread bleiben. Wenn die Zusammenhänge aber nur lose sind, ist ein eigener Thread einfach übersichtlicher. Um von einem Thema auf ein anderes zu verweisen und Kontexte herzustellen, gibt es immer noch das, was Hypertext ausmacht, nämlich einen Link. 😉
Tschö, Auge
Hallo Nico R.,
zum Thema „wie vermeide ich das ' Zeichen“ hätte ich diese Anmerkung:
json_encode($toreArray, JSON_HEX_APOS)
codiert Apostrophe automatisch als \u0027. Das Anführungszeichen " wird von json_encode automatisch als " escaped.
Es gibt noch eine andere Alternative:
<script type="text/plain" id="objekt_1">
<?=htmlspecialchars(json_encode($toreArray))?>
</script>
und dann später, wo man es braucht:
let toreArrayDB = document.getElementById("objekt_1").textContent;
type="text/plain" ist nicht Vorschrift, es kann irgendwas sein. Solange es kein vorgegebener Typ ist (wie text/javascript, module oder importmap), repräsentiert so ein script-Element für den Browser einen Datenblock, den er nicht zu interpretieren hat.
Rolf
@@Rolf B
Es gibt noch eine andere Alternative:
<script type="text/plain" id="objekt_1"> <?=htmlspecialchars(json_encode($toreArray))?> </script>
[…] type="text/plain" ist nicht Vorschrift, es kann irgendwas sein.
Nö, es sollte das sein, was für JSON vorgesehen ist: application/json
.
So mache ich’s auch bei den CSSBattle daily targets. Und auch bei den CSSBattle records.
Die JSON-Daten in <script id="daily-targets" type="application/json">
im HTML-Panel, das HTML-Template im JavaScript-Panel. Verkehrte Welt?
Kwakoni Yiquan
Hallo Rolf,
die Frage lag mir schon auf der Zunge.
json_encode($toreArray, JSON_HEX_APOS)
codiert Apostrophe automatisch als \u0027. Das Anführungszeichen " wird von json_encode automatisch als " escaped.
Hat im Test funktioniert 👍
Gruß Nico