JSON Exception aus http Request abfangen

In diesem Forum gibt es Starthilfe zum neuen Extension-System von phpBB 3.1/3.2. Fragen zur Entwicklung von Extensions und zur Konvertierung von phpBB 3.0.x MODs sind ebenfalls willkommen.
Antworten
Benutzeravatar
Mike-on-Tour
Supporter
Supporter
Beiträge: 1076
Registriert: 13.01.2020 21:09
Kontaktdaten:

JSON Exception aus http Request abfangen

Beitrag von Mike-on-Tour »

Verschiedene Rückmeldungen zur Usermap haben mich (nach Ausprobieren) zu der Erkenntnis geführt, dass ich noch einen Bug in der Abfrage der Geonames Datenbank habe, nämlich dann, wenn sie einen Fehlercode (heißt da Status) zurückgibt, z.B. wenn man versucht, einen ungültigen Benutzernamen anzugeben.
Die Abfrage ist wie folgt geschrieben:

Code: Alles auswählen

$json_request = "http://api.geonames.org/postalCodeSearchJSON?username=" . $this->gn_username . "&style=short&postalcode=" . $postal_code . "&country=" . $country;
$json = file_get_contents($json_request);
$xml = json_decode($json, true);
Ich habe jetzt den Originalcode eingestellt, auch wenn mir inzwischen selbst aufgefallen ist, dass in Zeile 2 ein '@' fehlt, um die Fehlermeldungen zu unterdrücken (ist inzwischen ergänzt, aber mit wäre mir wahrscheinlich noch nicht aufgefallen, dass da was nicht klappt - und irgendwann sieht man seine eigenen Fehler ja nicht mehr).

Im Erfolgsfall lautet die Rückgabe:

Code: Alles auswählen

{"postalCodes":[{"adminCode2":"00","adminCode3":"03151","adminName3":"Landkreis Gifhorn","adminCode1":"NI","lng":10.7391,"countryCode":"DE","postalCode":"29378","adminName1":"Niedersachsen","ISO3166-2":"NI","placeName":"Wittingen","lat":52.72805}]}
Im Fehlerfall, z.B. bei unbekanntem Nutzernamen:

Code: Alles auswählen

{"status":{"message":"user does not exist.","value":10}}
Ich hatte das über die Adresszeile des Browsers alles ausprobiert und bekam auch immer das erwartete Ergebnis. Also ging ich davon aus, dass ich ja nur abfragen muss, welcher Schlüssel im Rückgabe-Array enthalten ist, "status" oder "postalCodes", um dann entweder die gültigen Daten auszulesen oder in die Fehlerbehandlunc zu gehen.

Leider unterscheidet sich, wie ich jetzt weiß, die Rückgabe, wenn ich das aus einem php-Skript heraus mache, dann bekomme ich im Fehlerfall nämlich nicht diese Statusmeldung in der Variablen '$json', sondern diese hat den Wert 'false'.

Für diesen Fall habe ich jetzt den Code ergänzt:

Code: Alles auswählen

if (!$json)
{
	print_r($http_response_header);	// Testausgabe
}
Die Ausgabe sieht dann so aus:

Code: Alles auswählen

Array ( [0] => HTTP/1.1 401 Unauthorized [1] => Date: Mon, 08 Jun 2020 11:54:27 GMT [2] => Server: Apache/2.4.6 (CentOS) mod_jk/1.2.41 OpenSSL/1.0.1e-fips PHP/5.4.16 [3] => Cache-Control: no-cache [4] => Access-Control-Allow-Origin: * [5] => Content-Length: 56 [6] => Connection: close [7] => Content-Type: application/json;charset=UTF-8 ) 
Es wird also Inhalt zurückgegeben, der in Typ (s. Header[7]) und Länge (s. Header[5] => ... 56) mit der obigen Statusmeldung übereinstimmt.
Aber jetzt bin ich an dem Punkt, an dem ich mich im Kreis drehe und einen kleinen Schubs in die richtige Richtung brauche: Wie komme ich an diesen Inhalt heran???

Der Vollständigkeit halber hier die schmale Erklärung von Geonames.
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2130
Registriert: 15.12.2014 10:19
Kontaktdaten:

Re: JSON Exception aus http Request abfangen

Beitrag von LukeWCS »

Es hat den Anschein, das Geonames über den Client entscheidet, wie es reagieren soll. Ich habe das eben mal getestet und es sieht so aus, als ob Geonames bei PHP kein JSON liefert, wenn der Benutzer nicht registriert ist. Das ist natürlich ein wenig kontraproduktiv. :wink: Dann triggert Geonames nämlich direkt einen 401er, sieht man ja auch schon bei deinen Codebeispielen. Sprich, es reagiert direkt der Server, nicht die API in dem Fall. Werte doch einfach das Array aus, das dir über $http_response_header geliefert wird.

Wenn der Dienst erreicht werden konnte und dementsprechend JSON zurückgeliefert hat, steht im ersten Element:
HTTP/1.1 200 OK

Wenn der Dienst nicht erreicht werden konnte weil der Benutzer ungültig ist und somit auch die JSON Struktur fehlt, steht im ersten Element:
HTTP/1.1 401 Unauthorized

Damit hast du alles was du brauchst um feststellen zu können, ob der Benutzer registriert ist.
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
Benutzeravatar
Mike-on-Tour
Supporter
Supporter
Beiträge: 1076
Registriert: 13.01.2020 21:09
Kontaktdaten:

Re: JSON Exception aus http Request abfangen

Beitrag von Mike-on-Tour »

Ja, das ist klar, aber irgendwo muss er doch noch Content versteckt haben, denn dessen Länge (im Element [5]: "Content-Length: 56") stimmt exakt mit der Länge der von mir geposteten Fehlermeldung überein. Das gilt auch für den Fall, dass der Nutzer zwar existiert, aber den Service noch nicht aktiviert hat, auch hier stimmt diese Angabe aus dem Element [5] mit der tatsächlichen Länge der (deutlich längeren) Fehlermeldung überein. Deshalb kam ich ja auf die Idee, dass da etwas "versteckt" ist.
Meine Sorge galt aber primär dem Fall, in dem die stündlichen, täglichen und wöchentlichen Abfrage-Quota überschritten werden, dafür habe ich nämlich die Auswahl eines weiteren Nutzers eingebaut (falls mehr als einer in den Einstellungen angegeben wurde). Das habe ich ausprobiert und da wird tatsächlich das Status-Array zurückgegeben, das ich dann auswerten kann. Die arbeiten hier also mit zwei verschiedenen Methoden. Das ist aber erstmal egal, die für meine Zwecke wichtigen Infos bekomme ich ja (ich habe das nach demStartbeitrag ausprobiert).
Wenn sonst keiner eine zündende Idee hat, baue ich aus der 'if (!$json) {...}'-Abfrage eine Fehlermeldung.
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2130
Registriert: 15.12.2014 10:19
Kontaktdaten:

Re: JSON Exception aus http Request abfangen

Beitrag von LukeWCS »

Ich denke du verstehst noch nicht so ganz. Content-Length gibt dir in dem Fall die Grösse des angeforderten Inhalts an, der durch deine Abfrage generiert wurde, soweit okay. Aber da ist nichts "versteckt". 401 heisst schlicht "Nicht autorisiert", du kommst also nicht an diese Daten ohne Autorisierung heran. Du wurdest also direkt vom Server abgelehnt. Das kann zwar auch per Skript getriggert werden, aber das Ergebnis ist trotzdem das gleiche: kein Zugriff. Es wäre aus Server Sicht ja auch kompletter Nonsens, wenn man trotz 401 auf die Daten zugreifen könnte. :wink:
Mike-on-Tour hat geschrieben: 08.06.2020 17:14 Wenn sonst keiner eine zündende Idee hat, baue ich aus der 'if (!$json) {...}'-Abfrage eine Fehlermeldung.
$json nur auf true/false abzufragen, ist zu ungenau. Denn es kann ja auch schlicht ein Verbindungsproblem sein, das würde ja dann auch ein false ergeben. Darum hab ich vorgeschlagen das Array auszuwerten, was von $http_response_header geliefert wird. Damit kannst du präzise feststellen ob der Benutzer schon existiert ist oder nicht. Und Quota kannst dann auch präzise abfragen, wenn HTTP/1.1 200 OK zurückgemeldet wurde, denn dann hast du auch eine JSON Struktur die du auswerten kannst. Wenn dagegen HTTP/1.1 401 Unauthorized zurückkommt, brauchst gar nicht weiter zu machen, denn die Verbindung zum Dienst wurde blockiert und es gibt keine JSON Struktur.

Das bei Geonames im Falle von Zugriffen per PHP ein 401 getriggert wird wenn ein ungültiger Benutzer angegeben wurde, ist natürlich unschön. Da hätte man besser die gewohnte JSON Struktur schicken können mit der Fehlermeldung als Status. Aber, ist halt nicht.
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
Antworten

Zurück zu „Extension Bastelstube“