PHP Sammelthread: Zend Framework und alles was dazugehört

versuchst du gerade einen ErrorController zu emulieren? ;)

Nein, ich versuche gerade hinzubekommen, dass der Inhalt für Seiten die nicht existieren aus der Datenbank ausgelesen werden (wenn dort vorhanden; sonst am besten zum ErrorController weiterleiten).
Und da ich keinen Controller für einige Seiten erstellen möchte (damit ich ganz leicht per Datenbank ohne an Dateien zu "fuschen" Unterseiten erstellen kann), habe ich mir nun überlegt einen zentralen Controller zu nehmen (IndexController) und dieser sorgt dann dafür.

Wobei.. Hm.. wenn ich meine Standardroute umschreibe, so dass controller/action immer die Standardwerte index/index haben und in der URL die Werte dann intern als controller2/action2 oder so gehandhabt werden... Aber das hört sich für mich irgendwie "dreckiger" an als die Vorgehensweise die ich nun beabsichtige.
 
also ehrlich gesagt klingt das für mich mehr nach einer RewriteRule:

Code:
https://www.chrissel.de/aktuelles
=> Artikel: aktuelles

https://www.chrissel.de/referenzen/4
=> Artikel: Referenzen
=> Artikelnummer (der Artikelgruppe): 4

von daher klingt das für mich eher danach als ob du eine neue RewriteRule für die default-Regel festlegen solltest, einfach alles fehlerhafte (und das macht das Flag) auf den IndexController weiterzuleiten, ist ein Hack.
 
Ich möchte schon bei dem Standardaufbau bleiben:
www.example.com[/module][/controller][/action]
www.example.com[/controller][/action]

Und wenn nun eine Unterseite PHP-Code usw. braucht wird von mir ein Controller dafür angelegt, sollte das nicht der Fall sein existiert kein Controller und es soll automatisch aus der DB das Template geladen werden (wenn es nicht gerade gecached wurde usw. usf.).
Von daher finde ich die Möglichkeit mit dem Default-Controller der bei nicht existierenden Controllern benutzt wird schon ganz gut. Nur fehlt mir eben dann im IndexController die Information, welcher Controller mit welcher Action eigentl. angesprochen wurde.
 
Kannst du nicht einfach dort, wo du Action und Controller überschreibst das in die Registry packen?
Vl. unsauber, fällt mir aber am ehesten dazu ein. Was du noch versuchen könntest, ist an das Original Route-Object ranzukommen. Meiner Meinung nach werden da ja die Parameter nicht verändert.
 
Kannst du nicht einfach dort, wo du Action und Controller überschreibst das in die Registry packen?
Vl. unsauber, fällt mir aber am ehesten dazu ein.

Wird ja normal in den ZendFramework Dateien alles geregelt, ich setze nur den einen Parameter "useDefaultControllerAlways" des Dispatchers auf true.

Was du noch versuchen könntest, ist an das Original Route-Object ranzukommen. Meiner Meinung nach werden da ja die Parameter nicht verändert.

Das kann ich mal schauen ob da etwas verändertes drin steht. An das Objekt kommt man ja ziemlich leicht im Controller dran ;)


EDIT:

Okay. Ich habe hier nun etwas funktionierendes:
In meinem IndexController:
PHP:
    public function preDispatch()
    {
        $request = Zend_Controller_Front::getInstance()
            ->getRouter()
            ->route(new Zend_Controller_Request_Http());        
        $this->getRequest()->setModuleName($request->getParam('module'));
        $this->getRequest()->setParam('module', $request->getParam('module'));
        $this->getRequest()->setControllerName($request->getParam('controller'));
        $this->getRequest()->setParam('controller', $request->getParam('controller'));
        $this->getRequest()->setActionName($request->getParam('action'));
        $this->getRequest()->setParam('action', $request->getParam('action'));
    }

Aber die Lösung kommt mir mal total dämlich und dreckig vor.

Ich glaube da ist es doch wohl besser eine eigene Route zu basteln und default/index/index als Standard zu nehmen, was auch nicht überschrieben werden kann.
Mal gucken wie sich das mit meiner Sprachroute vereinbaren lässt.
Hierachiemäßig müsste dann nur die default-Route vor meiner neuen Route greifen, denn wenn ein Controller existiert (worauf ja die default-Route dann matched[?!]) soll dieser ja genommen werden. Falls nicht wird als nächstes meine Route genommen die schaut ob das Template existiert, falls nicht matched diese auch nicht. (-> eigenes Routingobjekt??)


EDIT2:

Hmpf, mit den Routen ist das auch doof. Dann muss ich in vielen ZF-Teilen die Erkennung umstellen, ob die aktuelle URL eine gegebene URL ist, die Links müssen überall richtig gebildet werden, ... und denke noch mehr Funktionen gehen mir verloren.
Muss ich das doch wohl ähnlich der Methode oben machen. Jemand eine bessere Idee wie ich wieder die alten Parameter herstellen kann, außer durch erneutes Routing?

EDIT3:

Um nicht erneut routen zu müssen speichere ich nun über ein Plugin mittels dem routeShutdown-Hook die Parameter.

Solange überhaupt jemand diese Editierungen liest :D
 
Zuletzt bearbeitet:
begrüße!

nachdem ich euch so lange verschont habe mal wieder eine frage von mir :D

für die dokumentation eines prozesses habe ich in einer datenbank mehrere verschiedene attribute.. die attribute sind über die datenbank frei konfigurierbar..
(es geht hierbei nicht um prozesse im sinne der informatik sondern im sinne des qualitätsmanagement.. also eigentlich nur irgendwas, das dokumentiert werden soll, wobei man attribute vordefinieren kann ;) )

in der regel gibt es für die attribute jeweils ein textfeld, in das man den gewünschten text schreibt.. es soll jetzt aber auch möglich sein, anstelle des textfelds eine "funktion" mit einem attribut zu verknüpfen.. es steht dann in der datenbank als content_type nicht "text" sondern zb "related_processes".. wenn dort related_processes steht, dann soll eine bestimmte methode aufgerufen werden und der rückgabewert dieser methode dann als "inhalt" in das attribut geschrieben werden..

wir würdet ihr das lösen? am einfachsten wäre es natürlich über einen einfachen switch.. das wäre aber wohl nicht besonders elegant.. könnte man sowas über ActionHelper lösen?
und habt ihr vielleicht eine idee, wie man das lösen könnte, ohne den html code direkt in die jeweilige methode, die den inhalt erzeugen soll, schreiben zu müssen?

ich hoffe das war einigermaßen verständlich ;)

bin über jeden tip dankbar :)

mfg
whizzler
 
Also ich habe es nicht verstanden :biggrin:

Die Dokumentation eines Prozesses (Eigenschaft) kann ein Freitext oder ein Verweis auf eine Methode (OOP) sein (Referenz) ?

Unter der Annahme, dass ich dies richtig verstanden habe:
Ein Switch ist natürlich möglich, jedoch müsste man den Code immerwieder neu anpassen, ich würde es da eher etwas generischer anfassen:
PHP:
$pb = new ProcessBroker();
$pb->addProcess('prozess1', new ProcessBrocker_Text('QA der Hauptniederlassung'));
$pb->addProcess('prozess2', new ProcessBrocker_Method('SomeClass', 'someMethode'));

echo $pb->getProcess('prozess2'); // String

aber das dynamische Aufrufen von Methoden kommt mir alles andere als koscher vor, falls möglich, beschreibe doch nocheinmal genauer zu welchem Zweck dies gemacht wird und was die Rückgabe im Detail ist. Denn theoretisch könnte man ja auch ein View-Partial oder ähnliches bei prozess2 einfügen, der diese String-Representation hat.
 
Du hast in einer Datenbank ein freies Feld in der du jeglichen Inhalt schreiben kannst und ein Feld in welchem der Typ von dem anderen Feld steht?
Wenn der Typ ganz normal nur 'content' o.ä. ist, dann willst du auch genau den Inhalt wieder bekommen und falls der Typ 'function' oder so ist wird die zugehörige Funktion zum Inhalt des freien Feldes aufgerufen?

Falls es so sein sollte und du mit Models für die Tabellen / Zeilen / Einträge arbeitest, würde ich in deinem Model für den Eintrag (also z.B. ein Kind von Zend_Db_Table_Row_Abstract) einfach eine Methode getContent() oder so machen, die das alles behandelt.
In der kannst du dann ja einfach über $this->type oder so den Typ bekommen und dann per Switch (so wie du es erwähnt hast) je nach Typ entweder den Inhalt direkt zurückgeben, die Rückgabe einer Methode, ... ??!
 
Die Dokumentation eines Prozesses (Eigenschaft) kann ein Freitext oder ein Verweis auf eine Methode (OOP) sein (Referenz) ?

so kann man es kurz und einfach sagen! oder man kann einen viel zu langen und viel zu wirren text schreiben wie ich :ugly:

aufgrund deines posts habe ich mir folgenden ansatz ausgedacht..
der controller kümmert sich nicht weiter um das dynamische aufrufen der jeweiligen methode..
im view wird ein view helper verwendet.. der view helper ruft dann die jeweilige methode auf.. (ob ich die methode dann direkt auf dem model aufrufe oder ne extra klasse dafür mache weiß ich noch nich.. im prinzip wäre ne neue klasse nur nen wrapper.. hätte aber den vorteil, dass nicht alle funktionen des models zur verfügung stehen und man ne größere flexibilität hat was die namensgebung angeht) der rückgabewert der methode wird dann mithilfe eines partials direkt gerendert.. dann muss ich mich nur an eine gewissen namenskonvention für die partials halten.. aber da würde ich dann wohl die konvention für die namen der view skripte übernehmen..

ich würde dann natürlich einschränkungen mit einbauen, welche werte für methodennamen erlaubt sind und welche nicht..
 
im view wird ein view helper verwendet.. der view helper ruft dann die jeweilige methode auf.. (ob ich die methode dann direkt auf dem model aufrufe oder ne extra klasse dafür mache weiß ich noch nich..
klingt in meinen Ohren so, als würde Applikationslogik in den View verlagert.
Das Auflösen der Prozedur usw. ist sicherlich nicht gut im View aufgehoben, der sollte nur noch rendern, was er an Daten reinbekommt mehr nicht.

ich würde dann natürlich einschränkungen mit einbauen, welche werte für methodennamen erlaubt sind und welche nicht..
was natürlich auch bedeuten würde, dass wenn man falsche Daten übergibt, und der View die Auflösung macht, könnten im View-Part Exceptions fliegen, Fehler nun sichtbar? ;)

Edit: ehrlich gesagt war die View-Partial-Idee im Nachhinein keine gute Idee, hatte nur mal schnell Ideen, die mir kamen, aufgeschrieben.
 
an das mit dem exceptions hatte ich nicht gedacht..

andere idee:
im controller wird ein array mit den einzelnen attributen erstellt..

Code:
array (
   0 => array(
               attribut_name => 'name',
               content => array(),
               partial => 'partial.phtml'
           )
   1 => array(
               attribut_name => 'name2',
               content => array(),
               partial => 'partial2.phtml'
           )
)

die dynamischen methodenaufrufe finden dann im controller statt.. der rückgabewert der methode, also die "rohdaten" werden dann in "content" gespeichert.. wenn es für das attribut nur freitext gibt, dann steht dort eben ein string und kein array.. partial ist dann logischerweise der name des partials.. dieser wird nach den namens konventionen für view skripts vom namen der methode abgeleitet..

im view wird dann der partial aufgerufen und der content übergeben und der partial rendert das ganze dann..
 
hi

sorry wegen doppelpost, aber sonst liest es ja keiner ;)

gibt es im zf eine fertige möglichkeit um die aktuelle uri zu bestimmen? ich brauche die aktuelle uri im view, um den user zb nach dem anmelden wieder auf die ursprüngliche seite schicken zu können..

eigentlich müsste es sowas doch geben.. aber ich habe nix gefunden.. bevor ich jetzt selber was schreibe dachte ich mir ich frag nochmal nach ;)

und wenn ich mir dann selber was schreibe, dann führt an der $_SERVER superglobal kein weg vorbei, oder? habe hier auch nix für gefunden im framework.. aber ansonsten gibt es anstelle von den superglobals ja eigentlich immer ne extra komponenten (session und request zb)
 
gibt es im zf eine fertige möglichkeit um die aktuelle uri zu bestimmen?

Zend_Controller_Request_Http->getRequestUri();;)

und wenn ich mir dann selber was schreibe, dann führt an der $_SERVER superglobal kein weg vorbei, oder? habe hier auch nix für gefunden im framework.. aber ansonsten gibt es anstelle von den superglobals ja eigentlich immer ne extra komponenten (session und request zb)

Zend_Registry?
 
Ich brauch mal wieder eure Hilfe :)

Ich versuche ein Formular per Ajax abzuschicken, in dem auch ein File-Upload Feld ist.
Das klappt aber so gar nicht, mein Form-Validator sagt immer, dass das Formular ungültig: "File 'pic_upload' exceeds the defined ini size"
Wenn ich das Formular allerdings normal absende, funktoinierts :roll:

Der Fehler kommt aus der Klasse Zend_Validate_File_Upload und gehört zu der Konstante INI_SIZE.

Mein Uploadfeld erstelle ich so:
PHP:
            $picUpload = new Zend_Form_Element_File('pic_upload');
            $picUpload->setLabel('Bild hochladen')
                      ->setAttrib('size', '66')
                      ->setValueDisabled(true)
                      ->addValidator('Count', true, 1)
                      ->addValidator('Size', true, 307200)
                      ->addValidator('Extension', true, 'jpg,jpeg,png,gif');
            $this->addElement($picUpload);

Ich habe schon versucht, das ganze ein wenig zu debuggen, aber ich weiß nicht so recht, wo ich da anfangen soll :roll:
In der Validator Klasse in der Methode isValid() habe ich mir $files in der ersten (erfolgreichen) Bedingung ausgeben lassen, und dort ist der Index 'error' schon auf 1. Aber wo der herkommt, hab ich noch nicht herausgefunden :(

Weiß da zufällig jemand weiter?
 
File-Uploads funktionieren mit Ajax nunmal nicht, von daher wird das immer fehlschlagen.
Nimm mal isValidPartial() ;)
 
So, ich hab mal eine kleine Frage zum Unit-Testing. Ist mir zwar ursprünglich beim PR-Test in Java aufgefallen, trifft aber hier genauso zu.

Ich habe eine Klasse, die irgendwas darstellen soll, im Beispiel einen Baum.
PHP:
class Tree {
   public $node = array('key'   => 1,
                        'left'  => null,
                        'right' => null);

   public insert($key);
   public height();
   public delete($key);
}
Nun will ich einen Unit-Test dazu schreiben. Jetzt besteht aber das Problem, dass ich z.B. für height() und delete() bereits einen erstellten Baum brauche.

Wie baue ich den jetzt auf? Die insert()-Methode kann man ja nicht wirklich verwenden, denn wenn die fehlerhaft ist, failt gleich der komplette Testcase.

Mir kam jetzt einfach mal in den Sinn, einen serialized String zu generieren und in dann zu deserialisieren, denn dann kann ich sowohl auf privates zugreifen, als auch die Referenzen der Nodes untereinander aufbauen. Ich halte das jetzt aber nicht unbedingt für eine schöne Lösung.:(

Andere Ideen?
 
mit insert ;)
das bei einer kaputten insert-Methode dann einige Tests fehlschlagen können ist klar, aber das hast du recht schnell herausgefunden ;)

Dein serialisierter String macht nur weit mehr Probleme als du brauchen kannst, immerhin ändert man gerne mal die Implementierung einer Klasse, mit dem serialisierten String fährst du dann die Tests an die Wand ;)
Zudem betrachtest du beim Unit-Testing die Klassen ja meist als Blackbox ;)

Nachtrag: Test-Dependencies (@depends) könnten das Problem auch lösen, habe ich aber noch nie gesehen, dass es real genutzt wurde.