Notizen zu meinem PHP Framework die Anwendungen in PHP betreffend
$q = http_build_query( array( 'foo[a]' => 123, 'foo[b]' => 'bar', 'name' => 'boo', 'amt' => '€ 2.59' ) ); $res = array(); parse_str ( $q, &$res ); echo $q, print_r($res,1); foo%5Ba%5D=123&foo%5Bb%5D=bar&name=boo&amt=%E2%82%AC+2.59 Array ( [foo] => Array ( [a] => 123 [b] => bar ) [name] => boo [amt] => € 2.59 )
Die Programmstruktur meines Framework besitzt sämtlichen Merkmale die einen MVC charakterisiert.
Bei jedem Request wird eine Instanz derjenigen Klasse erzeugt die per Konfiguration/Routingtable an den URL gebunden ist. Diese Instanz implementiert das Modell und besitzt Methoden zur Datenbeschaffung und Methoden die das View erzeugen und dazu bspw. ein Template rendern..
Je nach Request, Klasse und Konfiguration wird ein jedes View mit einem bestimmten Content-Type erstellt und ausgeliefert. In der Regel lautet der Content-Type: text/html.
In meinem FW Ist der Kontroller eine Methode der Instanz derjenigen Klasse welche per´statische Route an den URL gebunden ist.
In einem anderen Forum: Hat sich doch mal einer darüber mockiert, daß Perl gar kein richtiges OOP kann sondern daß da nur Referenzen mit dem Namen einer Klasse gesegnet werden. Was er nicht sagt! Aber gucken wir mal was PHP da macht:
public PDOStatement::fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] ) : mixed
Ach!
# Und so geht das dann: class main{ public $FILEDIR = "d:/home/files"; function selfdump(){ print_r($this); } } require "factory/_dbh.php"; $m = new main(); $pdo = _dbh( $m, array('myweb') ); $sth = $pdo->prepare("SELECT * FROM forum WHERE mesgid=39"); $sth->execute(); $r = $sth->fetchObject('main'); # Gebe den Namen einer Klasse mit $r->selfdump();
WOW: Die Daten können Methoden aufrufen! Na dann auf zum MVC by PHP+MySQL. Immerhin wird über den PDO::STH der Konstruktor der angegebenen Klasse gerufen die auch als Code vorliegen muss. Da werden auch sämtliche Eigenschaften zugewiesen.
Wenn es für eine Antwortseite erforderlich ist, ermöglicht das Framework den Austausch des kompletten BODY-Templates. Darüber hinaus ermöglicht die eingesetzte Templating-Engine die Anwendung einfacher Kontollstrukturen innerhalb eines Templates, so können einzelne Abschnitte eines Templates ein- oder ausgeblendet werden, je nachdem was das MVC-Datenmodell für die Sicht auf die Response (Antwortseite) vorsieht.
Das Bild zeigt die Entwicklung der Codeverteilung für mein Framework. In den Versionen 1 und 2 meines FW wurde bei jedem Request sämtlicher Code kompiliert, auch Code für Anwendungen, die nicht requested wurden. Gerouted wurde jedoch auch bereits in den ersten Versionen statisch anhand der Klassenbindung.
Erst die Version 3 brachte infolge konsequenter Anwendung der Vererbung hinsichtlich der Codeverteilung den entscheidenden Durchbruch. Was sich natürlich auch bestens auf die Performance auswirkt. Kompliliert wird nur noch der Code welcher zum Ausführen der requesteten Anwendung erforderlich ist.
Infolge weiterer Teilung des Codes und Auslagerung dessen in eine Factory konnte die Effizienz weiter gesteigert werden. So ist die Aufteilung von Code in Methoden der Factory die konsequente Fortsetzung der Organisation von Code in Klassen.
Ein typisches Beispiel für eine Methode der Factory ist eine Funktion zur Herstellung einer Sitzung mit MySQL. Charakteristisch deswegen weil eine MySQL Verbindung in nur wenigen Anwendungen gebraucht wird.
Des Weiteren werden durch die nun auch in PHP angewandte Klassenhierarchie + Factory Coderedundanzen nicht nur weitgehend sondern generell vermieden.
Aktuell werden 433 Seiten einschließlich Anwendungen vom Framework/Version 3 ausgeliefert und die meisten Seiten über eine gemeinsame Klasse (Common-Class). Anwendungen haben entweder eine eigene Klasse oder ein zur Common-Class hinzukonfiguriertes Interface (Trait). Welche Komponenten das sind, verrät ein Blick in den Quelltext einer jeden Seite.
Anwendungen für dieses Framework entwickeln heißt, ein Plugin zu enwickeln was entweder eine dedizierte Klasse sein kann oder ein Trait. So lassen sich Erweiterungen innerhalb extrem kurzen Zeiten entwickeln und in der Regel genügen dazu Grundkenntnisse der jeweiligen Programmiersprache.
Kaum zu glauben, PHP kennt Sonnenauf- und Untergang als Builtinfunktion. Sonnenaufgang: 07:56 Uhr, Sonnenuntergang: 17:25 Uhr, diese Angaben sind für Frankfurt/Main und natürlich aktuell für den heutigen Tag (06.02.2023).
Wie schon im Perl-Framework, habe ich die Factory für das PHP-Framework in Traits organisiert. So wird der Code für Methoden, die nicht im Namespace der Klasse definiert sind, aus dem Dateisystem nachgeladen und ausgeführt. Um bspw. ein Database-Handle (PDO-Objekt) zu bekommen genügt ein Funktionsaufruf:
$dbh = $this->_dbh($this->base());
Wobei auch hier dafür gesorgt ist, daß die der Methode entsprechende Datei _dbh.php
nur einmal eingebunden wird. Der Code wird also gecached und auf diese Art und Weise gibt es auch keine Coderedundanzen. Zentralorgan der Factory ist die Magic Method __call()
die auch den Zugriff (Getter und Setter) auf die Eigenschaften der aktuellen URL regelt.
Wie schon in Perl ist nun auch im PHP Framework die Factory das Herzstück, was Instanzen um Code erweitert, der im Moment der Instanzerstellung noch gar nicht feststeht.
Für den einfachen Zugriff auf die Konfiguration zu einem URL:
$title = $this->title(); $this->title('Neuer Titel für die Seite');
Der Name einer Eigenschaft wird als Funktion verwendet, welche die Eigenschaft zurückliefert und auch setzen kann.
Das Framework ermöglicht die Ausgabe von text/html
abweichenden und beliebigen Content-Types wie Grafik, Audio, Video, PDF usw. in einer HTTP Response.
Woher der BODY für eine Seite vom Type text/html
geladen wird, regelt das Atribut file
(Beispiel = phpnotizen.html) in der Konfiguration. Sofern dieses Attrtribut nicht gesetzt ist, liegt der Body bzw. das Template für den Body in der Klassendatei sauber getrennt vom PHP-Bereich. Andere Quellen sind konfigurierbar. In der Regel jedoch ist für den Body ein Template vorgesehen was als Datei im Templateverzeichnis vorliegen muss und damit ist dieses Template auch für die Volltextsuche verfügbar. Das Template in der Klassendatei ist somit die Ausnahme und bspw. sinnvoll für die Klasse NotFound
wo sich der Body auf nur wenige Zeilen beschränkt.
Deprecated Codefragments habe ich bereinigt und auch Einiges verbessert was die Anwendung vereinfacht:
function bodybuild(){ $tt = new Template5( array( 'template' => $this->BODY )); $tt->AddParam($this->STASH); $tt->EchoOutput(); }
Äußerst nützlich beim Entwickeln ist die Möglichkeit, einen Dump der beteffenden Daten im Browser ausgeben zu können. Von daher habe ich diese Möglichkeit, wie schon in meinem Perlframework, auch in der PHP Variante fest eingebaut. Zum Beispiel ist es hiermit möglich einen Dump der für diese Seite zu rendernden Platzhalter im Browser auszugeben. Des Weiteren sind diese Attribute als HTML-Kommentar im Kopfbereich einer jeden Seite eingebaut was eine etwaige Fehlersuche erleichtert.
Der in PHP integrierte Parser liefert Request-Parameter in $_GET
, $_POST
, $_REQUEST
und Uploads in $_FILES
. Dafür kennt der Parser die Content-Types application/x-www-form-urlencoded und multipart/form-data die ein Request mit sich bringt sofern ein HTTP-Message-Body anhänglich ist. In Hinblick auf Webservices, REST, SOAP und XMLRPC kann ein Request jedoch auch andere Content-Types mit sich bringen die es zu verabeiten gilt. Eine diesbezügliche Erweiterung ist in meinem Framewok über eine dedizierte Klasse class CGI
realisiert. So erfolgt der Zugriff auf Request-Parameter nicht mehr über die o.g. Arrays sondern einheitlich per $this->param('name')
.
Diese Erweiterung macht den Transportlayer HTTP und Request-Methoden wie GET, POST, PUT usw. vollständig transparent für nachgelagerte Anwendungen, was ja auch in Sinne des Standards CGI/1.1 ist.
Für mich keine Frage, ein Framework muss von der Version der Programmiersprache in der es entwickelt wurde, unabhängig sein. Mein PHP-Framework jedenfalls läuft unter PHPv5.3 aufwärts. Was bestimmte Erweiterungen bzw. spezielle Anwendungen betrifft, das ist eine ganz andere Frage. Dieser Grundsatz ergibt sich allein schon aus der Idee die eine Templating Engine einschließt welche ein Framework sogar von der Progrmmiersprache unabhängig macht.
File LastModified: 03.02.2020
E ist vollbracht, siehe Dateidatum obenstehend: Wie in Perl, so ermöglicht nun auch die PHP Variante meines Framework den Einbau beliebiger Platzhalter wie z.B. den Platzhalter %filedate%
für obenstehende Ausgabe. Zur Realisierung dieses Features betrachten wir zunächst die Konfiguration:
[/phpnotizen.htm] file = phpnotizen.html interface = date parent = /php class = Dummy title = Blog zu meinem PHP Framework descr = Notizen zu meinem PHP Framework die Anwendungen in PHP betreffend vanguard = 1
Wie die Bezeichnung für die Klasse schon vermuten lässt, ist diese Klasse eine Dummyklasse die nichts weiter zu tun halt, als von der mainClass
alle Methoden zu erben. Das Attribut interface = date
jedoch sorgt dafür, daß die Methoden des Framework-Interface, die in der mainClass
definiert sind, nicht ausgeführt werden. Stattdessen werden Methoden ausgeführt die in der zum Interface gehörigen Datei date.php
definiert sind. Diesen Methoden wird die Instanz der zum URL konfigurierten Klasse übergeben, also die Instanz der Klasse Dummy
. Diese Instanz referenziert sämtliche zum Request/Responsezyklus gehörigen Daten und so ist es möglich, auch die Platzhalter für diese Seite zum Leben zu erwecken.
Für die Konfiguration statischer Routen (URL - Klassenbindung) ergeben sich damit im Framework sehr vielfältige Möglichkeiten, sowohl zum Einbau dynamischer Inhalte als auch zum Programmieren interaktiver Webanwendungen sowie Webservices wie untenstehendes HTML-Object zeigt:
Das data-Attribut für dieses Objekt referenziert den Parameter jsondate=1 welcher die hier vorliegende Seite damit um einen Webservice erweitert.
Mit der Erstellung einer Instanz stehen bekanntlich auch die Methoden fest welche diese Instanz ausführen kann. Mein Framework jedoch ermöglicht den Austausch bestimmter Methoden nachdem die Instanz erstellt wurde, ganz einfach durch die Konfiguration. So ist es möglich, eine bestehende Webressource z.B. interaktiv zu machen oder um einen Webservice zu erweitern. Oder anders ausgedrückt: Ein hinzukonfiguriertes Interface ermöglicht einer jeden Seite die Verarbeitung von Benutzereingaben bzw. Parametern.
Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. sos@rolfrost.de und wenn Sie möchten daß mein Prepaid nicht verfällt können Sie mich auch gerne anrufen 01625 26 40 76.