steve!: Problem beim verarbeiten eines JSON-Objektes

Hallo!

Ich frage von MaqQuest die Api (http://www.mapquestapi.com/directions/#advancedSample) ab und lasse mir das Ergebnis als JSON zurückgeben. Da habe ich jetzt unerwartet Schwierigkeiten, weil ich annahm, ich kann das Ergebnis mit json_decode in ein Array umwandeln.

Was ich erhalte, sieht gekürzt so aus:
---schnipp---
renderAdvancedNarrative({"route":{"hasTollRoad":false,"computedWaypoints":[],"fuelUsed":0,"shape":{"maneuverIndexes" ... "info":{"copyright":{"text":"© 2012 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif","imageAltText":"© 2012 MapQuest, Inc."},"statuscode":0,"messages":[]}});
---schnipp---

Mache ich danach ein json_decode($response); und lasse mir das mit var_dump(); ausgeben, erhalte ich NULL.

Ich seh meinen Fehler nicht bzw. verstehe ich da vielleicht etwas falsch?
Im Vergleich zu den JSON-Arrays, die ich sonst kenne, kommt mir das "renderAdvancedNarrative(" am Anfang der Rückgabe merkwürdig vor.

Habe versucht, das mit str_replace rauszunehmen, auch das ");" am Ende, aber am Ergebnis des json_decode ändert sich nichts.

Habt ihr einen Tipp für mich?

  1. Im Vergleich zu den JSON-Arrays, die ich sonst kenne, kommt mir das "renderAdvancedNarrative(" am Anfang der Rückgabe merkwürdig vor.

    Das scheint, als würde hier eine Funktion rundherumliegen und das Objekt selbst ist nur ein Argument davon

    Habe versucht, das mit str_replace rauszunehmen, auch das ");" am Ende, aber am Ergebnis des json_decode ändert sich nichts.

    Hätte ich auch gemacht, ja.

    Habt ihr einen Tipp für mich?

    Zeichencodierung? Das hier scheint mir irgendwie schief gelaufen zu sein:

    "© 2012 MapQuest, Inc."

    Entferne einfach mal Teile des Objekts und schau ab wann der Fehler auftritt - das PHP-Error-Reporting könnte ebenfalls helfen.

    1. Danke!

      Hab die Sache noch mal von Null angefangen zu programmieren. Habe noch einal "renderAdvancedNarrative(" rausgeworfen, dann bei json_decode noch den Schalter fürs Dekodieren in ein Array auf 'true' gesetzt und jetzt ein aktzeptables Ergebnis erhalten. Ist mir schleiferhaft, warum MapQuest das JSON so "komisch" zurückliefert.

      Jetzt komme ich klar, nächste Aufgabe ist die Sortierung eine mehrdimensionalen Arrays :)

      1. Hi,

        Ist mir schleiferhaft, warum MapQuest das JSON so "komisch" zurückliefert.

        Sieht nach einem JSONP-Interface aus. Dadurch wird der zurückgegebene String zu JavaScript-Code, der einen Funktionsaufruf enthält, wobei als erster Parameter das Objekt übergeben wird.

        Bis die Tage,
        Matti

      2. Tach!

        nächste Aufgabe ist die Sortierung eine mehrdimensionalen Arrays :)

        Du hast eine Baumstruktur vorliegen, kein mehrdimensionales Array im eigentlichen Sinne. Die einzige nervenschonende Vorgehensweise ist usort() und Konsorten. array_multi_sort() ist weniger sinnvoll.

        dedlfix.

        1. Du hast eine Baumstruktur vorliegen, kein mehrdimensionales Array im eigentlichen Sinne. Die einzige nervenschonende Vorgehensweise ist usort() und Konsorten. array_multi_sort() ist weniger sinnvoll.

          Ah ok. Vielen Dank für den Hinweis. Hatte es jetzt schon mit array_multi_sort() probiert, aber kein Ergebnis hinbekommen. Problem bei usort() war für mich, wie ich denn den Schlüssel übergebe, nach welchem sortiert werden soll.

          Der sieht in meinem Fall so aus "['location']['distance']".

          1. Tach!

            Problem bei usort() war für mich, wie ich denn den Schlüssel übergebe, nach welchem sortiert werden soll.

            Wenn du nach Schlüsseln sortieren willst, musst du uksort() nehmen. Vielleicht reicht sogar ksort(). Die u-Funktionen brauchst du nur, wenn die zu vergleichenden Werte komplexer als nur einzelnen Skalare (z.B. String, Integer) sind.

            Der sieht in meinem Fall so aus "['location']['distance']".

            Da hast du nicht _einen_ Schlüssel vorliegen, sondern einen Schlüssel und im Element ein weiteres Array, also eine hübsches komplexes Gebilde. Mit print_r() kannst du dir das ansehen (vorher ein <pre> ausgeben).

            dedlfix.

            1. Wenn du nach Schlüsseln sortieren willst, musst du uksort() nehmen. Vielleicht reicht sogar ksort(). Die u-Funktionen brauchst du nur, wenn die zu vergleichenden Werte komplexer als nur einzelnen Skalare (z.B. String, Integer) sind.

              Hm, nein nicht nach Schlüsseln. Will nach den Werten sortieren, die unter diesem Schlüssel liegen.

              Nur wie gebe ich, nach welchem Schlüssel aus dem Array, das Array sortiert werden soll?

              Hintergrund: ich habe eine Liste von Locations, deren [distance] vom aktuellen Aufenthaltort des Nutzers ich mir per MapQuest berechnen lasse.
              Diese [distance] schreibe ich mit ins Array der Location rein, naemlich unter dem Schluessel ['location']['distance'].
              Am Ende will ich diese Liste sortiert nach ['location']['distance'] zurückgeben.

              im Element ein weiteres Array, also eine hübsches komplexes Gebilde. Mit

              Ich hasse hübsch komplexe Gebilde :-))))

              1. Tach!

                Hm, nein nicht nach Schlüsseln. Will nach den Werten sortieren, die unter diesem Schlüssel liegen.
                Nur wie gebe ich, nach welchem Schlüssel aus dem Array, das Array sortiert werden soll?

                Also Formulierungsfehler, auch hier wieder. Du willst konkret nach dem Wert eines zugehörigen Schlüssels sortieren. Dann usort() oder uasort(), wenn du die Schlüssel des zu sortierenden Arrays noch brauchst.

                In der benutzerdefinierten Funktion bekommst du zwei Parameter übergeben. Lass dir die mal anzeigen (var_dump()/print_r() und gleich danach ein die(), weil einmal anzeigen reicht und nicht für jeden Vergleichsvorgang erneut). Du wirst dann vielleicht zwei Arrays sehen

                Array (
                    ['distance'] => inhalt
                    ['anderes_zeug'] => anderer_inhalt
                )

                Über $a['distance'] kannst du dann an inhalt ran.

                dedlfix.

  2. Moin!

    Was ich erhalte, sieht gekürzt so aus:
    ---schnipp---
    renderAdvancedNarrative({"route":{"hasTollRoad":false,"computedWaypoints":[],"fuelUsed":0,"shape":{"maneuverIndexes" ... "info":{"copyright":{"text":"© 2012 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif","imageAltText":"© 2012 MapQuest, Inc."},"statuscode":0,"messages":[]}});
    ---schnipp---

    Mache ich danach ein json_decode($response); und lasse mir das mit var_dump(); ausgeben, erhalte ich NULL.

    Ich seh meinen Fehler nicht bzw. verstehe ich da vielleicht etwas falsch?
    Im Vergleich zu den JSON-Arrays, die ich sonst kenne, kommt mir das "renderAdvancedNarrative(" am Anfang der Rückgabe merkwürdig vor.

    Das ist eine waschechte Javascript-Funktion, die deswegen da ist, weil du vermutlich nicht JSON, sondern JSONP abrufst. Gute JSONP-Interfaces erlauben, diese Javascriptfunktion durch den Aufrufer defineren zu lassen. Du solltest nochmal prüfen, in welchen Modus du die API-Ausgabe angefordert hast, bzw. wie du reines JSON erzwingst.

    Ein anderer wichtiger Hinweis: json_decode($string); erzeugt dir ein Gemisch von Arrays und stdClass-Objekten. Das ist eventuell nicht so schön, deswegen kennt die Funktion noch einen zweiten Parameter, der dafür sorgt, dass du nur Arrays bekommst: json_decode($string, true);

    - Sven Rautenberg