Zur Navigation

Server side PHP / JSON response script gesucht

(keine XML response)

1 klaus2

Ich möchte einem existierenden GET Request die richtige Antwort geben. Es handelt sich dabei um die Abfrage von Geodaten (zu einem weissen Fleck in Bezug auf Postleitzahlen), die in einer selbst erstellten MySQL Datenbank enthalten sind.

Der Request wird als URL mit Parametern abgeschickt: http://ziel.server.tld/script.php?parameter=value&parameter=value
Ich tausche den Zielserver URL gegen meinen eigenen URL aus. Bisher habe ich mit meinem selbst geschriebenen Script keinen Erfolg, die Antwort wird nicht akzeptiert. Ich vermute, dass mein Script die Werte nicht so zurück gibt, wie die Response auf den GET Request erwartet wird.

Zu diesem Thema habe ich im Internet einige recht umfangreiche PHP Classes gefunden, möchte aber den Aufwand und die Komplexität auch wegen der Response-Zeit in Grenzen halten. Wer kann mir helfen?

Gruss,
klaus2

05.05.2012 20:45

2 Jörg Kruse

Bisher habe ich mit meinem selbst geschriebenen Script keinen Erfolg, die Antwort wird nicht akzeptiert.

Von wem bzw. was wird die Antwort nicht akzeptiert? handelt es sich um ein serverseitiges Script, das diesen Request an den anderen Server ausführt? und wird irgendeine Fehlermeldung ausgegeben, die Aufschluss darüber geben könnte, warum die Antwort nicht akzeptiert wird?

Ich vermute, dass mein Script die Werte nicht so zurück gibt, wie die Response auf den GET Request erwartet wird.

Da ist die Frage, was für ein Format erwartet wird? in der Überschrift schreibst du "JSON response" - also wird die Antwort wohl mit json_encode() kodiert werden müssen, das ist in deinem Script der Fall?

05.05.2012 21:07

3 klaus2

Hallo Jörg,

Wenn ich den original-Server abfrage bekomme ich einen String zurück, der json_encode-ed ist:

{"postalCodes":[{"Country_code":"DE","Zip_code":"64823","City":"Gro\u00df-Umstadt","Lat":"49.8678","Lng":"8.9339","Accuracy":"0"}]}

Ausserdem die Meldung:

geocode.php:-1Resource wurde als Dokument interpretiert, aber mit MIME-Typ application/json übertragen.

Ich habe in meinem Script eine php "echo" Ausgabe und den Rückgabe-String json_encode-ed und den entsprechenden Header-Wert gesetzt:
header('Content-type: application/json;charset=UTF-8;');
.

Vielleicht mache ich aber einen grundsätzlichen Denkfehler: Muss das Response-Script vielleicht eine Funktion sein??? Mit php "return" bekomme ich keinen Wert zurück.

Klingelt da bei Dir irgendwas?

MfG,
klaus2

05.05.2012 21:44

4 Jörg Kruse

Ausserdem die Meldung:

geocode.php:-1Resource wurde als Dokument interpretiert, aber mit MIME-Typ application/json übertragen.

Ist das die JavaScript-Konsole von Safari? probier mal mit einem anderen Browser, was da für ein Fehler erscheint

Der Content-Type-Header scheint richtig gesetzt, er erscheint ja auch in der Fehlermeldung.

Ich würde aber mal den Output validieren, z.B. hier:

http://jsonlint.com/

Muss das Response-Script vielleicht eine Funktion sein??? Mit php "return" bekomme ich keinen Wert zurück.

Am Ende musst du den kodierten Inhalt schon ausgeben, z.B. mit echo. Das siehst du aber ja auch, wenn du die URL direkt im Browser aufrufst. return wird nur innerhalb einer Funktion verwendet

05.05.2012 22:06 | geändert: 05.05.2012 22:07

5 klaus2

Habe den original URL in JSONLint validiert - ist korrekt, mein URL liefert mit der echo Ausgabe kein JSON zurück:

Results

Parse error on line 1:

^
Expecting '{', '['

Meine Ausgabe sieht so aus:
			$my_response = array (
				'postalCodes'=>$postalCodes = array ( 
					'Country_code'=>strtoupper($row["Country"]),
					'Zip_code'=>$row["Zip"],
					'City'=>$row["City"],
					'Lat'=>$row["Latitude"],
					'Lng'=>$row["Longitude"],
					'Accuracy'=>$row["Accuracy"] 
				)
			);
			$ret_result = json_encode($my_response);
			echo $ret_result;

Deshalb suche ich ja nach Beispielen :-(

05.05.2012 22:20

6 Jörg Kruse

Results

Parse error on line 1:

^
Expecting '{', '['

Hast du da eine Leerzeile ganz am Anfang oder ist die Ausgabe komplett leer?

Die Leerzeile kannst du vermutlich erst sehen, wenn du die Quelltextanzeige im Browsers aufrufst.

Wenn gar nichts ausgegeben wird, ist an deinem Script wohl irgendwo etwas im Argen. Ein leerer Array würde eher so kodiert werden:

[]

Der Codeabschnitt, den du hier gepostet hast, ist aber soweit OK

Error-Reporting hast du in deinem PHP-Script eingeschaltet?

05.05.2012 22:37 | geändert: 05.05.2012 22:40

7 klaus2

Hallo Jörg, vielen Dank schon mal bis hierher.

Ein Fehler ist gefunden: der gzip encoding war eingeschaltet (ist auf dem original-Server auch ein). Jetzt bekomme ich eine valide JSON Antwort. Allerdings gibt es da einen Unterschied, der vermutlich beim Parsen der Antwort relevant ist:

Original-Antwort:
{
"postalCodes": [
{
"Country_code": "DE",
"Zip_code": "64823",
"City": "Groß-Umstadt",
"Lat": "49.8678",
"Lng": "8.9339",
"Accuracy": "0"
}
]
}

Meine Antwort:
{
"postalCodes": {
"Country_code": "KE",
"Zip_code": "80315",
"City": "MAKTAU",
"Lat": "-3.4000000",
"Lng": "38.1333330",
"Accuracy": "0"
}
}

Wie bekomme ich die zusätzlichen eckigen Klammern in die Antwort? In meinem Array sind die nicht drin.

			$ret_result = json_encode($my_response = array (
				'postalCodes'=>$postalCodes = array ( 
					'Country_code'=>strtoupper($row["Country"]),
					'Zip_code'=>$row["Zip"],
					'City'=>$row["City"],
					'Lat'=>$row["Latitude"],
					'Lng'=>$row["Longitude"],
					'Accuracy'=>$row["Accuracy"] 
					)
			));
			$content_length = "Content-Length: ". strlen($ret_result);
			header($content_length);
			echo $ret_result;

06.05.2012 11:24

8 Jörg Kruse

Da scheint noch ein nicht-assoziatives Array dazwischenzuhängen:

            $ret_result = json_encode($my_response = array (
                'postalCodes'=>$postalCodes = array ( 
                    array (
                        'Country_code'=>strtoupper($row["Country"]),
                        'Zip_code'=>$row["Zip"],
                        'City'=>$row["City"],
                        'Lat'=>$row["Latitude"],
                        'Lng'=>$row["Longitude"],
                        'Accuracy'=>$row["Accuracy"] 
                    )  
                )   
            )); 

nicht-assoziative Arrays werden von json_encode mit [] kodiert, assoziative Arrays mit {}

06.05.2012 11:57

9 klaus2

Hallo Jörg,

das war 'ne Punktlandung. Mit Einfügen des zusätzlichen Arrays wird meine Response akzeptiert und korrekt verarbeitet.

Noch eine abschliessende Frage:
Wenn ich in meiner DB den ZIP-Code bzw. das Land nicht drin habe (ist z.Z. beschränkt auf ein Land), kann ich die ursprüngliche Anfrage an den original-Server weiter leiten? Wenn ja, wie? Den Request-URL hätte ich ja ...

klaus2

06.05.2012 14:12

10 Jörg Kruse

Das einfachste wäre es wohl, den Inhalt mit file_get_contents() zu holen, dort kann man auch eine URL als Parameter angeben, siehe hierzu Beispiel #1 auf der betreffenden Manualseite:

http://php.net/manual/de/function.file-get-contents.php

Falls Einschränkungen in der php.ini dies verhindern, könnte man mit fsockopen() eine Socket-Verbindung aufmachen ud darüber einen HTTP-Request senden. Auch hierzu gibt es auf der Manualseite unter #1 ein passendes Beispiel:

http://www.php.net/manual/de/function.fsockopen.php

Danach kannst du den empfangenen Inhalt ausgeben

Edit:

einfach weiterleiten ginge natürlich auch:

header('Location: http://www.example.com/script.php?parameter=value');

06.05.2012 14:41 | geändert: 06.05.2012 14:45