PHP Datenbank per JSON übermitteln

Boeby

Lieutenant
Registriert
Sep. 2006
Beiträge
945
Hallo erstmal,

Irgendwie steh ich aufm Schlauch. Und zwar mache ich mir Gedanken wie ich z.b. Datenbankeinträge abfragen kann, und die Antwort als JSON erhalte.

Ausgehend von folgendem Beispiel:
Angenommen ich habe im Web einen Server mit einer "normalen" relationalen Datenbank die die Einträge tabellarisch als Webseite darstellt. (Ausgelesen altmodisch mittels PHP).
Nun möchte ich ein anderes GUI erstellen z.b. in Form einer App fürs Handy. JSON finde ich hübsch und praktisch.
Wie erstelle ich nun am saubersten eine Verbindung zwischen dem Client und dem Server, welcher dieses JSON aus der DB heraus generieren muss ? Am schönsten wäre natürlich wenn ich dies anhand von Kriterien aus meinem Request erstellen könnte.

Klar ich könnte bei jedem Get-Request auf eine bestimmte PHP-Seite einen String zurückgeben, welcher durch Schlaufen gebildet wird und aus hardcodeten Syntax-Fetzen besteht.
Doch irgendwie muss das sauberer gehen...?

Auf dem Server soll keine spezielle Sprache eingesetzt werden. Es soll alles mittels PHP realisiert werden. Python, JS (Node.js) und anderes möchte ich nicht einsetzen, da es dann vlt mein Problem für einmal löst, aber nicht für weitere Beispiele.

Falls sich jemand schonmal mit solchen Gedanken herumgeschlagen hat (worin ich mir sehr sicher bin), wäre ich dankbar um ein paar Tipps..
 
Wenn du nur auf PHP setzen willst, dann musst du dich an das Request-Response - Modell halten.
Was sicherheitstechnischer Selbstmord wäre: Querys als String an den Server schicken und von diesem prüfen lassen.

Was bleibt dir also? Schreib eine REST-ful API in PHP, deren Rückgabewert entweder komplettes HTML oder nur die JSON-kodierten Daten sind, je nach Request-Variable.

Nimm dir als Beispiel z.B. die Armory von WoW. Da hat man eine schöne Request-Struktur mit entsprechenden Antworten.
 
Das Request-Response Model ist mir lieb. Das passt soweit.
Bezüglich Sicherheit gibt es fast nichts zu beachten. Der zu verwendende User hat nur Leseberechtigung und alle Daten wären sowiso auch auf der Webseite ersichtlich. Logins oder dergleichen gibt es in diesem Beispiel nich

Daaron schrieb:
Was bleibt dir also? Schreib eine REST-ful API in PHP, deren Rückgabewert entweder komplettes HTML oder nur die JSON-kodierten Daten sind, je nach Request-Variable.

Nimm dir als Beispiel z.B. die Armory von WoW. Da hat man eine schöne Request-Struktur mit entsprechenden Antworten.
Meine grosse und zentrale Frage: "Wie schreibe ich eine REST-ful API ?"
PHP deshalb weil das auf jedem Webserver (Webhoster) vorhanden ist, und ich nicht glaube, noch viel mehr zu benötigen.

Hast du mir weitere Informationen von Armory ?
http://blizzard.github.com/api-wow-docs/
Die Doku sieht zwar schön aus, aber ich glaube das hilft mir nicht. API Dokumentationen kenne ich leider zu genüge..


@Hancock
Hast du mir einen Link zu dieser Library ? PHP und JSON Library findet keine brauchbaren Ergebnisse.:( (Okay vielleicht einen Vergleich aus 2006.. :rolleyes:)

Ich weiss nicht ob ich auf dem Holzpfad bin, aber das Thema ist sehr sehr dürftig wie ich finde.. Ist ja nicht so dass ich der erste bin der über sowas nachdenkt ? Und falls doch, wie lösen den andere dieses Problem ?
 
Zuletzt bearbeitet:
Boeby schrieb:
Meine grosse und zentrale Frage: "Wie schreibe ich eine REST-ful API ?"
PHP deshalb weil das auf jedem Webserver (Webhoster) vorhanden ist, und ich nicht glaube, noch viel mehr zu benötigen.
REST klingt schlimmer als es im Endeffekt ist. Kerngedanke: Jede Ressource ist eindeutig über einen URL-Aufruf ansprechbar.
In der Armory würde das dann grob so aussehen: armory.wow-europe.com/SERVER/CHARACTER/TALENTTREE -> gibt den Talentbaum von nem Char auf einem bestimmten Server zurück.
Das sind am Ende immer verschachtelte switch-case - Strukturen.

Aber wenn du von Webhostern ausgehst: Wieso bist du dir so sicher, dass dein DB-User keinen Schindluder treiben kann? Nicht überall kannst du weitere User anlegen und ihnen Rechte geben.
Außerdem kann man über ungeprüftes SQL noch viel mehr machen als nur die aktuelle Datenbank abzufragen. MySQL Queries können Shell Commands auf dem Server auslösen...
 
@Daaron,

Klingt irgendwie nach Apache Modul "mod_rewrite" ? Kenne mich damit nicht aus, aber weiss in etwa was es bezweckt. Dieser Pfad "/SERVER/CHARACTER/TALENTTREE" gibt es ja nicht wirklich sondern wird im Hintergrund in Variablen abgefüllt, wenn ich das richtig verstehe..

Bezüglich der Sicherheit hast du selbstverständlich recht, auch wenn ich jetzt nicht wüsste wie man mittels Query ein Shellcommand ausführen kann. Aber das ist ein anderes thema.
Mein Ziel ist es nicht irgendwelche sql-queries zu übertragen sondern z.b. getUser.php?id=XXX aufrufen zu können und danach alle Informationen des Users zu erhalten. XXX würde ich dann noch prüfen nach Bereich und vorallem auf SQL Injections untersuchen. Aber das ist dann reguläres PHP und darüber finde ich genügend im Netz. Daher habe ich das Thema heruntergespielt.


@Hancock
Danke für den Link. Darauf lässt sich später aufbauen. Ich bin in objektorientiertem PHP noch nicht fit, aber daran arbeite ich. (Objektorientierung ist ansich ist kein Problem, habe mit Java viel Erfahrung)


Was ich nun noch suche ist z.b. ein Buch oder umfangreicheres Tutorial o.ä, welches mir eine Architektur aufzeigt.. Oder zumindest die Ideen dahinter. Damit es dann eben nicht in Switch/Case Abfragen ausartet.. Oder glaubt ihr, ich stelle mir das zu schwierig/umfangreich vor ?

Habe derzeit im Sinn mindestens eines dieser Bücher zu kaufen:
http://www.amazon.com/gp/product/05...=1789&creative=390957&creativeASIN=0596529260
http://www.amazon.com/gp/product/18...=1789&creative=390957&creativeASIN=1847195520

Danke soweit für die Antworten. Habt mir schon einige Fragen beantwortet!
 
Boeby schrieb:
Klingt irgendwie nach Apache Modul "mod_rewrite" ? Kenne mich damit nicht aus, aber weiss in etwa was es bezweckt. Dieser Pfad "/SERVER/CHARACTER/TALENTTREE" gibt es ja nicht wirklich sondern wird im Hintergrund in Variablen abgefüllt, wenn ich das richtig verstehe..
Korrekt. Das sind URL Rewritings für z.B. index.php?site=armory&server=SERVERNAME&character=CHARNAME

Solche Rewrites machen das Leben aber um einiges einfacher, weil man ne hübsche Struktur hat. Und natürlich freut sich Google darüber.

Was ich nun noch suche ist z.b. ein Buch oder umfangreicheres Tutorial o.ä, welches mir eine Architektur aufzeigt.. Oder zumindest die Ideen dahinter. Damit es dann eben nicht in Switch/Case Abfragen ausartet.. Oder glaubt ihr, ich stelle mir das zu schwierig/umfangreich vor ?
Switch ist doch hübsch übersichtlich. Besser als endlose If-Konstrukte.
 
Ich glaub, du willst dir zu schnell Bücher kaufen, jetzt schreib erst mal Code, der das macht, was du brauchst und dann wird das schon.

Learning by doing, nicht alles erst theoretisch durchkauen. Machen und lernen, geht schneller und bringt dir mehr.

Wenn du die DB schon hast, dann schreib mal deine PHP-Seite und lass es dir im Browser anzeigen. Dann siehste, was rauskommt.

BTW: Meine Methode ist sehr speicherintensiv, falls du also mehr als 100 Zeilen deiner Datenbank ausgeben willst, ist es performanter, das ganze zu Fuß zu machen:
PHP:
echo '[';
while($erg=$prep->fetch(PDO::FETCH_ASSOC)){
echo '{';
foreach($erg as $key=>$t)
echo '"'.$key.'":"'.$t.'",';
echo "}";
}
echo ']';
 
Man macht es solange, bis man an die Grenzen stößt, und das machen die wenigsten. Was du vorgeschlagen hast ist einfach eine unnötige und falsche premature optimization. Wenn er nie an die Grenzen stößt, dann braucht er deinen Code auch nicht. Zumal dein Code nur unter ganz bestimmten Vorraussetzungen korrekt arbeitet: Key und Value beinhalten keine Hochkommata, Value ist ein String (keine Zahl, kein null, kein Array/Objekt, kein boolescher Wert), es muss ein Unicode oder ASCII Zeichensatz sein usw.
 
Zuletzt bearbeitet:
allein aufgrund der Skriptlaufzeiten fragt man doch eh nie ALLE Objekte an und gibt sie zurück. Man fragt erst an, wie viele Resultate es für einen gegebenen Query gibt und schreibt danach ne Pagination, bei der die Daten häppchenweise geliefert werden. Ich brauch niemandem 1000 Datensätze schicken, wenn ihn nur der 280ste interessiert.
 
Hancock schrieb:
@Daaron:
Aber wenn du alle Datensätze brauchst, dann lohnt sich es doch nicht, diese Häppchenweise anzufordern.
Auch die App wird die Daten nicht komplett anzeigen sondern häppchenweise verarbeiten. Warum? RECHENLEISTUNG!
Du kannst eher einen Server damit betrauen, die Daten vorzusortieren und Stück für Stück zu liefern als einem Client alle Daten ungefiltert vor die Füße zu knallem, insbesondere einem schwachen Mobile-Client mit wenig RAM. Oh, und natürlich müssen die Daten auch übertragen werden... was für Payment-Modelle haben Mobilclients oftmals? Genau...

Ist dir nie aufgefallen, dass alle Bildergalerien, Newslisten, Foren,.... ein Pagination-System nutzen oder per AJAX beim runterscrollen weitere Daten anfordern? Warum tun sie das wohl?
 
... Bildergalerie
brauchen sehr viel Traffic, Bilder halt. Da kostet ein Round-Tip nicht viel Zeit und Traffic, aber ein nicht-angezeigtes Bild ist z.B. auf 9gag die Regel (v.a. will niemand warten, bis die 100 MB Bilder geladen sind, wenn die Seite sofort alles anzeigen würde).

Newslisten: Usenet? Das ist ne Schwäche des Protokolls, oder warum verwenden die ganzen Clients mehrere parallele Leitungen, das ist ja soo resourcenschonend.

Foren: Ich kenn keins, welches Daten aus Leistungsgründen mit AJAX anfordert. Pagination kannste auf 100 Seiten erhöhen, wenn du willst, aber das ist unübersichtlich.

Rechenleistung, Smartphone: Ich glaub, du weißt nicht, was die für bums haben können, auf'm Android läuft Windows 95 im Emulator bedienbar. Jetzt sag mir net, dass da 1000 Datensätze auf einmal das Handy überfordert. Aber ne Latenz von >200 ms ist normal, 1000 Datensätze wären dann 200*1000*2=400.000 ms =400 ms, viel Spass.

Traffic: Ja und bei ner Info von 1 KB rechnet es sich, Traffic von 1 KB an HTTP-Code zu erzeugen, einen PHP-Thread/Prozess zu starten und ne Datenbankverbindung aufzubauen.

BTW: Server haben auch nur endlich viel RAM, wenn jetzt 1000 Clients 1000 Datensätze a 1KB anfordern, dann sind das z.B. schon 1 GB RAM. Bei ner sauberen MySQL-Implementation wird der Datensatz erst generiert, wenn du ihnr brauchst, also keine Speicher"verluste" und PHP kann schon ein Teil senden, während die Datenbank noch rechnet.
 
Hancock schrieb:
Newslisten: Usenet? Das ist ne Schwäche des Protokolls, oder warum verwenden die ganzen Clients mehrere parallele Leitungen, das ist ja soo resourcenschonend.
Ich meinte kein Usenet, sondern stink normale New-Webseiten. Die zeigen alle nur die 10-20 aktuellsten Beiträge an, alles was älter ist verbirgt sich entweder in einem separaten Archiv, in einer Pagination oder hinter Ajax-Calls (z.B. bei netzwelt.de. sehr cool gemacht)

Foren: Ich kenn keins, welches Daten aus Leistungsgründen mit AJAX anfordert. Pagination kannste auf 100 Seiten erhöhen, wenn du willst, aber das ist unübersichtlich.
Nur weil du kein Forum kennst, dass weitere Posts per AJAX anfordert, heißt das nicht, dass es a) nicht existiert und b) nicht möglich ist. Es wäre auf jeden Fall sinnvoller, als einen 2.000-Post - Thread auf einen Schlag zu laden... genauso wie eine Pagination.
Und niemand erwartet, dass eine Pagination übersichtlich ist, genau so unübersichtlich ist aber auch, wenn du deinem User alle 2.000 Posts auf einen Schlag in die Fresse knallst.

Traffic: Ja und bei ner Info von 1 KB rechnet es sich, Traffic von 1 KB an HTTP-Code zu erzeugen, einen PHP-Thread/Prozess zu starten und ne Datenbankverbindung aufzubauen.

BTW: Server haben auch nur endlich viel RAM, wenn jetzt 1000 Clients 1000 Datensätze a 1KB anfordern, dann sind das z.B. schon 1 GB RAM. Bei ner sauberen MySQL-Implementation wird der Datensatz erst generiert, wenn du ihnr brauchst, also keine Speicher"verluste" und PHP kann schon ein Teil senden, während die Datenbank noch rechnet.
Du raffst es einfahc nicht. Ich sage nicht "sende jeden Datensatz einzeln" sondern "teile die Datensätze in handliche Blöcke, statt sie als einen Monster-Block zu senden".

Ich würde z.B. hier im Forum nicht jeden möglichen Post eines älteren Threads empfangen wollen, obwohl mich nur die letzten 20 Posts interessieren. Ich würde aus einer Shoutbox nicht die gesammelten Werke der letzten 2 Jahre sehen wollen, sondern nur die Posts der letzten 2-3 Tage.
 
Und du raffst es auch nicht, dass klein und handlich nicht immer praktischer ist.

Wenn du dir ein Film lädst, dann willst du auch nicht, dass der Sharehostermäßig in 100 Teile geteilt ist, das hat ein Protokolloverhead, aber du willst auch nicht, dass der Server dir den Film zuerst bei sich in den RAM knallt und dann dir erst sendet. Stichwort Asynchron und Pipeline

Du willst wahrscheinlich nicht verstehen, dass es sinnvoll sein könnte, mehrere Sachen zu gruppieren und ruhig ein fettes Ding durchzuziehen, als alles zu fragmentieren und schön klein zu machen. Und wo ist der Unterschied zwischen "handliche Blöcke" und "einzeln" es gibt nur 1:n und n:m, abstrakt gesagt.

Ich glaub, dass wir unterscheiden müssen zwischen:
a) der Client weiß genau, welche Sachen er braucht
b) der Client lädt Sachen, die vielleicht wichtig sein könnten

Bei a spricht nix gegen ein einzelnes fettes Paket
Bei b spricht nix gegen AJAX und co, da Beispiel netzwelt wahrscheinlich nur 1 % aller Visitors herunterscrollt.

Für a muss dann der Server entsprechend darauf eingestellt sein, eben durch so ein "selbstgeschriebenen" JSON-Encoder (wie als wäre das so schwer).
 
Du schießt mit Kanonen auf Spatz, selbst bei 100KB JSON-Dateien ist der Aufwand und die Wartbarkeit da selbst einen JSON-Encoder zu schreiben nicht gerechtfertigt. Denn das was du als JSON-Encoder geschrieben hast, ist weit davon entfernt standardkonform zu sein, da fehlen noch einige Dinge.

Das sind einfach so sinnlose "premature optimizations" für Probleme, die höchstwahrscheinlich nie auftreten. Wenn du dann an jeder Ecke solch einen "Schwachsinn" optimierst haben wir ganz schnell den Grund warum PHP so einen schlechten Ruf hat, das ganze Projekt ist der reinste Bloat an Code und unwartbar weil an jeder Stelle aus "Performancegründen" hier und da etwas optimiert werden musste, was gar nicht relevant ist.


Es ist jedenfalls interessant, dass du klüger als die ganzen PHP Core-Devs, die Zend Framework und Symfony Devs zu sein scheinst, denn die haben alle keine Notwendigkeit in einem Streaming Json-Encoder gesehen, haben also keinen entwickelt.
 
Auch wenn du einen eigenen JSON-Encoder schreibst, was bringt dir das genau? Das eine PHP-Script, dass dann deinen Encoder laufen lässt, wird im Endeffekt ALLE Datensätze aus der DB lesen und verarbeiten, genauso wie es dann ALLE Datensätze an einen Client schickt, der im Zweifel gar nicht alle braucht sondern nur eine Hand voll.

Was du machen willst ist keine Aufgabe für einen PHP-Server sondern eher für eine Lösung wie Node.JS, die vollkommen eventgesteuert und asynchron arbeitet. Ein PHP-Script, das so arbeitet wie du es dir vorstellst, würde entweder am PHP Memory Limit oder an der max_execution_time scheitern.

Genau deshalb segmentiert man Anfragen bei PHP ja auch: Man will den Server nicht mit hirnlos monströsen Requests überlasten. Dabei ist es scheißegal, ob du jetzt einen eigenen JSON-Encoder geschrieben hast oder ob du den Array (nix anderes ist die Rückgabe eines SQL Requests) per Echo rauspumpst. Du fragst nach zu viel und das System wird umgehend zusammenbrechen. Deshalb: Divide et impera!
 
Zurück
Oben