mediengestalter.info
FAQ :: Mitgliederliste :: MGi Team

Willkommen auf dem Portal für Mediengestalter

Aktuelles Datum und Uhrzeit: Fr 19.04.2024 05:13 Benutzername: Passwort: Auto-Login

Thema: PHP Objektrepräsentation in JS vom 23.08.2010


Neues Thema eröffnen   Neue Antwort erstellen MGi Foren-Übersicht -> Programmierung -> PHP Objektrepräsentation in JS
Seite: 1, 2  Weiter
Autor Nachricht
Gargoyle
Threadersteller

Dabei seit: 19.05.2005
Ort: -
Alter: 39
Geschlecht: Männlich
Verfasst Mo 23.08.2010 13:20
Titel

PHP Objektrepräsentation in JS

Antworten mit Zitat Zum Seitenanfang

Hi Zusammen
Ich habe folgendes gemacht:
Um im Javascript Zugriff auf Eigenschaften meines Models zu erhalten, habe ich einen Helper geschrieben der ein Objekt entegennimmt, eine Json repräsentation davon erstellt (per json_encode) und daraus JS code generiert. Ungefähr so:
Code:

function jsHelper ($object, $binder=false)
{
if(empty($objects)) return;
        $opentag = "<script type='text/javascript'>";
        $closetag = "</script>";
       
        // allow single object
        $objects = (is_array($objects))?$objects:array($objects);
        // start the js object literal
        $js_object = '{ ';
        // bind the php objects
        foreach($objects as $name=>$object)
        {
            $encoding_object = (method_exists($object, 'jsonEncode'))?$object->jsonEncode():$object;
            $js_object .= $name.':'.json_encode($encoding_object).',';
        }
        // bind a dummy to prevent errors with the comma
        $js_object .= 'dummy:{}'
        // close the js object literal
        $js_object .= '}';
        // bind the data to an accessible js object
        $js_string = (!empty($binder))?$binder."={$js_object}":"window.phpJS = ".$js_object;
        // return the code
        return $opentag.$js_string.$closetag;
}
 

JsonEncode erzeugt ein vernünftiges Daten Objekt, da die json repräsentation z.B. eines CI Models nicht wirklich sinnvoll ist. Diese Methode muss dann noch über ein Interface definiert werden. Der Code bindet dann das Objekt an den Binder, hier z.B. an das window Objekt als phpJS. Beispiel:
Code:

//in der view
echo jsHelper(array('product'=>$product));
 

in meinem JS kann ich dann so auf das Objekt zugreifen
Code:

  if(window.phpJS.product)
  {
    // hier könnten z.B. Bilder von Optionen an ein selectfeld gebunden werden.
  }
  else
  {
    throw new Error('Product not available');
  }
 

Natürlich werden hier KEINE sensiblen Daten übergeben und der Code ist natürlich auch ohne JS funktionstüchtig.

Was haltet ihr davon?
Ist das allenfalls gängige Praxis oder ist das völliger BS?
Können hier browserspezifische Probleme auftreten?

Messi für Feedback
  View user's profile Private Nachricht senden
bacon

Dabei seit: 24.10.2007
Ort: -
Alter: -
Geschlecht: -
Verfasst Mo 23.08.2010 13:48
Titel

Antworten mit Zitat Zum Seitenanfang

Ich halte es für BS. Mal davon abgesehen, dass diese Funktion so wie sie da oben steht niemals wirklich ausgeführt wird:

Code:
function jsHelper ($object, $binder=false)
{
if(empty($objects)) return;


Weiter gehts nicht ($object != $objects).

Warum nicht einfach ein

Code:
<?php json_encode($object->toArray())?>


oder gleich

Code:
<?php $object->toJson();?>


Außerdem ist der Output der Funktion - würde sie denn etwas ausgeben - unbrauchbar, wenn Du JSON via XMLHttpRequest anforderst. Ich würde mich mal mit DataSource Mustern vertraut machen. Und vielleicht dem ArrayAccess-Interface (http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html)
  View user's profile Private Nachricht senden
Anzeige
Anzeige
Gargoyle
Threadersteller

Dabei seit: 19.05.2005
Ort: -
Alter: 39
Geschlecht: Männlich
Verfasst Mo 23.08.2010 14:43
Titel

Antworten mit Zitat Zum Seitenanfang

Das Ganze ist auch eher als View Helper gedacht.
bacon hat geschrieben:
Ich halte es für BS. Mal davon abgesehen, dass diese Funktion so wie sie da oben steht niemals wirklich ausgeführt wird:

Code:
function jsHelper ($object, $binder=false)
{
if(empty($objects)) return;


Weiter gehts nicht ($object != $objects).

Oh, das ist ein Tippfehler (die Weiche ist nur dazu da falls aus Versehen leere Arrays in die Funktion gelangen).
bacon hat geschrieben:

Warum nicht einfach ein

Code:
<?php json_encode($object->toArray())?>


oder gleich

Code:
<?php $object->toJson();?>


Hmm ja to Array würde wahrscheinlich sinn Machen, ist aber vom Prinzip her ja nicht wirklich ein Unterschied oder? Wie würdest du dann die Variable verfügbar machen für dein JS?
bacon hat geschrieben:

Außerdem ist der Output der Funktion - würde sie denn etwas ausgeben - unbrauchbar, wenn Du JSON via XMLHttpRequest anforderst. Ich würde mich mal mit DataSource Mustern vertraut machen. Und vielleicht dem ArrayAccess-Interface (http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html)

Das ist eben nicht der Sinn davon ... Ok, der Metodenname ist dumm gewählt jsonEncode ist nicht wirklich richtig, es soll allgemein einfach eine Art serialisierbare Repräsentation erzeugt werden, ein Data Transfer Object (Mann jetzt hab ich sicher 10 Minuten überlegt wie das nochmal heisst). Also unabhängig von der Struktur der entsprechenden Formalisierung, z.B. auch für die Verwendung im Zusammenhang mit einem Visitor, wobei das aber jetzt eigentlich über das Anliegen meines Posts herausgeht.

Es geht eben darum die Daten ohne weiteren Request an die View zu übergeben. Das ArrayAccess Interface kenn ich, benutze es aber eigentlich meist eher im Zusammenhang mit Composites.

Danke für dein Feedback, wie handhabst du denn die Übergabe von Daten an dein JS?


Zuletzt bearbeitet von Gargoyle am Mo 23.08.2010 14:44, insgesamt 1-mal bearbeitet
  View user's profile Private Nachricht senden
choise

Dabei seit: 01.02.2007
Ort: Würzburg
Alter: 35
Geschlecht: Männlich
Verfasst Mo 23.08.2010 14:55
Titel

Antworten mit Zitat Zum Seitenanfang

erstell doch einfach einen eigenen view für dein object wenn es zb per ajax angefragt wird oder route es anders



Zitat:
/object/view/6.json


oder sowas.
  View user's profile Private Nachricht senden Website dieses Benutzers besuchen
Gargoyle
Threadersteller

Dabei seit: 19.05.2005
Ort: -
Alter: 39
Geschlecht: Männlich
Verfasst Mo 23.08.2010 15:05
Titel

Antworten mit Zitat Zum Seitenanfang

choise hat geschrieben:
erstell doch einfach einen eigenen view für dein object wenn es zb per ajax angefragt wird oder route es anders
Zitat:
/object/view/6.json

oder sowas.


Das tue ich bereits *zwinker*. Ich find einfach den Ajax Request überflüssig und glaube halt in einer solchen DTO Repräsentation (die meine jsonEncode methode erzeugt) noch weitere Verwendungszwecke zu sehen, lasse mich aber auch gerne eines besseren belehren.
  View user's profile Private Nachricht senden
bacon

Dabei seit: 24.10.2007
Ort: -
Alter: -
Geschlecht: -
Verfasst Mo 23.08.2010 15:07
Titel

Antworten mit Zitat Zum Seitenanfang

Ich würde mir einfach mal überlegen, was genau Du überhaupt erreichen möchtest. Momentan rendert Dir das Ding mitten in Deine WebResponse 'n Script Tag und baut da JSON rein, das vorher recht krude zusammengefrickelt wird. - Mir erschließt sich da nicht so recht der Sinn oder vielmehr - das scheint mir irgendwie nicht mehr ganz KISS zu sein, in sich auch von der Architektur her komisch (Du setzt bspw. ein festes Datenschema voraus, um daraus ein festes Datenschema zu entwickeln - im Grunde sind aber Schemadefinition und Daten selbst zwei verschiedene paar Schuhe und auch zwei Aspekte eines Datencontainers).

Zitat:
z.B. auch für die Verwendung im Zusammenhang mit einem Visitor


Das gibt der Code aber nicht her. Das Besucher-Muster ist wenn ich mich recht entsinne etwas mehr (nicht viel mehr;) als 'ne If-Wurst ala if($request->isPost()) elseif ($request->isXmlHttpRequest())... etc.

Sowas wird üblicherweise weniger am Datenmodell abgefrühstückt als vorher bereits im Controller. Der fragt dann eben bedingt ab, was für ein Format denn ausgegeben werden soll und schaltet abhängig davon die View noch in bestimmte Modi (mit Layout, ohne, etc) sowie reichtert die Response mit entspr. Headern an. Dein Datenmodell wird ja selten direkt "besucht" - immer mal über sowas wie Separation of Concerns nachdenken.

Der View bei Übergabe des Datenmodells eine einheitliche Struktur zu verpassen ist natürlich gar nicht so doof, (gesetzt den Fall, wir bewegen uns in einer strengen MVC-Umgebung). Aber View-Helper für die Aufbereitung selbiger zu verwenden halte ich wiederum für die falsche Stelle. Aber gut... vielleicht hab ichs auch einfach nur nicht kapiert... Vielleicht kannst Du Dich ja mal mit dem IOC-Prinzip auseinandersetzen, da findest Du vielleicht ein wenig Inspiration.

Zitat:
benutze es aber eigentlich meist eher im Zusammenhang mit Composites.


Weiß nicht warum das eine das andere bedingen soll. Das ganze ist doch nur ein Proxy auf Accessoren - warum sollte man im einfachsten Falle Getter bspw. Setter denn auf komplexe Attribute beschränken?

Zitat:
Ich find einfach den Ajax Request überflüssig und glaube halt in einer solchen DTO Repräsentation (die meine jsonEncode methode erzeugt)


Ajax ist kein Selbstzweck, weil die Leute zu blöd sind, JSON-Daten selbst zu deserialisieren, sondern ein Mittel zum Steigern der User Experience... Daher finde ich das Argument "ich find ajax requests überflüssig weil ich mein json wieder selbst zu js render kann" irgendwie --- strange *zwinker*


Zuletzt bearbeitet von bacon am Mo 23.08.2010 15:16, insgesamt 2-mal bearbeitet
  View user's profile Private Nachricht senden
Gargoyle
Threadersteller

Dabei seit: 19.05.2005
Ort: -
Alter: 39
Geschlecht: Männlich
Verfasst Mo 23.08.2010 15:46
Titel

Antworten mit Zitat Zum Seitenanfang

bacon hat geschrieben:
Ich würde mir einfach mal überlegen, was genau Du überhaupt erreichen möchtest. Momentan rendert Dir das Ding mitten in Deine WebResponse 'n Script Tag und baut da JSON rein, das vorher recht krude zusammengefrickelt wird. - Mir erschließt sich da nicht so recht der Sinn oder vielmehr - das scheint mir irgendwie nicht mehr ganz KISS zu sein, in sich auch von der Architektur her komisch (Du setzt bspw. ein festes Datenschema voraus, um daraus ein festes Datenschema zu entwickeln - im Grunde sind aber Schemadefinition und Daten selbst zwei verschiedene paar Schuhe und auch zwei Aspekte eines Datencontainers).


Verständlicher Einwand. Schön gelöst sind die Methoden (resp die Helper Funktion) nicht, das steht ausser Frage. Aber ich möchte die Daten eben gerade nicht an ein festes Schema binden, sondern sie so aufbereiten das sie problemlos in ein solches gebracht werden können. json_encode kann z.B. kein CodeIgniter Model codieren (was ganz abgesehen davon gefährlich wäre dä im db abstraktions Layer Passwörter etc verfügbar sind), nehme mal an das liegt an Zirkelbezügen.

Grundsätzlich geht es mir jedoch wirklich in 1. Linie darum ob es blöd, resp unpraktikabel ist Daten aus PHP über injizierten js Code an ein überall verfügbares Objekt zu binden (quasi mit "globalem scope"? Grad keine Idee wie man das treffend ausdrückt).
bacon hat geschrieben:

Zitat:
z.B. auch für die Verwendung im Zusammenhang mit einem Visitor


Das gibt der Code aber nicht her. Das Besucher-Muster ist wenn ich mich recht entsinne etwas mehr (nicht viel mehr;) als 'ne If-Wurst ala if($request->isPost()) elseif ($request->isXmlHttpRequest())... etc.

Sowas wird üblicherweise weniger am Datenmodell abgefrühstückt als vorher bereits im Controller. Der fragt dann eben bedingt ab, was für ein Format denn ausgegeben werden soll und schaltet abhängig davon die View noch in bestimmte Modi (mit Layout, ohne, etc) sowie reichtert die Response mit entspr. Headern an. Dein Datenmodell wird ja selten direkt "besucht" - immer mal über sowas wie Separation of Concerns nachdenken.

Das tue ich normalerweise auch. Und es ist wahrscheinlich auch etwas gesucht, aber gerade bei grösseren Konstrukten wie z.B. WordPress find ich es einfach etwas Paradox die ganze Maschinerie noch einmal zu starten um Daten abzufragen die beim 1. Parsen der View bereits vorhanden sind.
Ehm nein ein Visitor ist wenn ich mich recht entsinne eine Art Decorator der z.B. durch Collections hindurchgereicht wird. Durch einen "Double dispatch" lassen sich dann Objekte z.B. loggen (abhängig vom übergebenen Visitor) ohne die Objekte selbst zu verändern. Edit: Was doch eigentlich der IOC Philosophie entspricht

bacon hat geschrieben:

Der View bei Übergabe des Datenmodells eine einheitliche Struktur zu verpassen ist natürlich gar nicht so doof, (gesetzt den Fall, wir bewegen uns in einer strengen MVC-Umgebung). Aber View-Helper für die Aufbereitung selbiger zu verwenden halte ich wiederum für die falsche Stelle. Aber gut... vielleicht hab ichs auch einfach nur nicht kapiert... Vielleicht kannst Du Dich ja mal mit dem IOC-Prinzip auseinandersetzen, da findest Du vielleicht ein wenig Inspiration.

Zitat:
benutze es aber eigentlich meist eher im Zusammenhang mit Composites.


Weiß nicht warum das eine das andere bedingen soll. Das ganze ist doch nur ein Proxy auf Accessoren - warum sollte man im einfachsten Falle Getter bspw. Setter denn auf komplexe Attribute beschränken?

Hehe sollte man nicht, ich mag halt einfach die Möglichkeiten im Zusammenhang mit dem Iterator, sonst hab ich es schlicht und einfach noch nicht viel verwendet ausser für Entity Klassen.

bacon hat geschrieben:

Zitat:
Ich find einfach den Ajax Request überflüssig und glaube halt in einer solchen DTO Repräsentation (die meine jsonEncode methode erzeugt)


Ajax ist kein Selbstzweck, weil die Leute zu blöd sind, JSON-Daten selbst zu deserialisieren, sondern ein Mittel zum Steigern der User Experience... Daher finde ich das Argument "ich find ajax requests überflüssig weil ich mein json wieder selbst zu js render kann" irgendwie --- strange *zwinker*

Hmm vielleicht ist das ganze halt einfach etwas gesucht Menno! Es geht wirklich nur um den Request da ja die Daten schon vorhanden sind ... * Keine Ahnung... *


Zuletzt bearbeitet von Gargoyle am Mo 23.08.2010 15:55, insgesamt 1-mal bearbeitet
  View user's profile Private Nachricht senden
bacon

Dabei seit: 24.10.2007
Ort: -
Alter: -
Geschlecht: -
Verfasst Mo 23.08.2010 16:22
Titel

Antworten mit Zitat Zum Seitenanfang

Zitat:
json_encode kann z.B. kein CodeIgniter Model codieren (was ganz abgesehen davon gefährlich wäre dä im db abstraktions Layer Passwörter etc verfügbar sind), nehme mal an das liegt an Zirkelbezügen.


Rekursive Abhängigkeiten sind immer mit gewissen Schwierigkeiten verbunden, allerdings sollte man alles, das in irgend einer Form persistiert sowieso nicht "einfach so" serialisieren (alleine schon, damit Deine Connection nicht plötzlich futsch ist. Es gibt die Methoden __sleep() und __wakeup() bzw. SPL::Serializable (http://www.php.net/~helly/php/ext/spl/interfaceSerializable.html). Ach ja: Schmeiß CodeIgniter in die Tonne - aber das Fass möchte ich natürlich hier nicht aufmachen *zwinker*

Zitat:
Grundsätzlich geht es mir jedoch wirklich in 1. Linie darum ob es blöd, resp unpraktikabel ist Daten aus PHP über injizierten js Code an ein überall verfügbares Objekt zu binden (quasi mit "globalem scope"? Grad keine Idee wie man das treffend ausdrückt).


Also ich persönlich halte es nicht für sinnvoll, aber wenn Du daraus für Dich irgendeine Best Practice generieren kannst, dann los...

Zitat:
Das tue ich normalerweise auch. Und es ist wahrscheinlich auch etwas gesucht, aber gerade bei grösseren Konstrukten wie z.B. WordPress find ich es einfach etwas Paradox die ganze Maschinerie noch einmal zu starten um Daten abzufragen die beim 1. Parsen der View bereits vorhanden sind.


Hm... es spricht ja nichts dagegen, dem Klienten Daten zu überlassen: Schau Dir doch mal die DataStore Implementierung hier an: http://framework.zend.com/manual/de/zend.dojo.data.html

Ich selbst bin zwar kein guter Freund von Frontend-Codegeneratoren, aber das ist sicher Geschmackssache. Da biste nämlich schnell wieder bei Anforderungen, die klassisches MVC nicht lösen kann - und da haben wir endgültig die Brücke zu Dependency Injection Containern geschlagen. JSF2 macht sowas ja vor. Um aber reine Datencontainer zu verwalten, würde ich immer einen Datastore mit einheitlicher API + Schema verwenden, damit sind deine Widgets im Frontend nämlich generell fütterbar.
  View user's profile Private Nachricht senden
 
Neues Thema eröffnen   Neue Antwort erstellen Seite: 1, 2  Weiter
MGi Foren-Übersicht -> Programmierung


Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst an Umfragen in diesem Forum nicht mitmachen.