AW: [PHP] Klassenstruktur für Adressdatenbank
Ja, das dass Unsinn ist, war klar.
Ich habe es jetzt so:
PHP-Quellcode:
Und das kommt auch an. Nur wie kann ich jetzt unterscheiden, ob es ein neuer Datensatz ist oder ob ein existierender bearbeitet wurde?
case "save":
$adressen = new DB_Adressen(); $adressen->name = $name; $adressen->vorname = $vorname; $adressen->save(); break; |
AW: [PHP] Klassenstruktur für Adressdatenbank
Dazu ist das $exists-Flag im Model da. Habe ich da nicht bereits im Ansatz was im Beispiel programmiert?
Die Theorie: Ein existierender Datensatz hat immer eine ID in Form eines auto_increments Wertes. Deswegen muss man beim speichern mysqli_insert_id() aufrufen um die neu erzeugte ID zu speichern. Ein Datensatz, der aus einem Query stammt hat eine ID gespeichert. Der Konstruktor des Models hat deswegen auch den optionalen exists-Parameter. Wenn jemand einen existierenden Datensatz holt und daraus ein Model erzeugt, sollte er darauf achten dieses Flag zu setzen. Das müsste in der get()-Methode im Beispiel doch eigentlich zu sehen sein? Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Das heißt, wenn ich das Form mit Daten eines schon existierenden Datensatzes fülle wird der Flag automatisch gesetzt?
Edit: Äh, nein, wird es nicht. Ich glaube, da brauche ich doch noch mal ein etwas ausführlicheres Beispiel mit einer Form Klasse. Und ich mache für heute erst mal Feierabend. |
AW: [PHP] Klassenstruktur für Adressdatenbank
Zitat:
Beispiele:
PHP-Quellcode:
$person = new DB_Adresse();
$person->name = "Mustermann"; $person->vorname = "Max"; var_dump($person->id); // NULL $person->save(); // INSERT var_dump($person->id); // 42
PHP-Quellcode:
$person = DB_Adresse::get(42);
echo $person->vorname . " " . $person->name; // Max Mustermann $person->email = "muster@example.com"; $person->save(); // UPDATE
PHP-Quellcode:
$person = new DB_Adresse();
$person->id = 42; $person->email = "muster@example.com"; $person->save(); // theoretisch INSERT, wirft aber eine Exception: Duplicate Primary Key (o.ä.)
PHP-Quellcode:
$person = new DB_Adresse(array(), true);
$person->email = "muster@example.com"; $person->save(); // theoretisch UPDATE, wirft aber eine Exception: cannot Update: id is NULL (noch nicht implementiert)
PHP-Quellcode:
An ein genaueres Beispiel werd' ich mich dann heut Abend machen. :)
$person = new DB_Adresse(array(), true);
$person->id = 42; $person->email = "muster@example.com"; $person->save(); // UPDATE Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Danke, aber ich werde wahrscheinlich erst am Sonntag wieder dazu kommen, an dem Projekt weiterzuarbeiten.
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Luckie,
entschuldige dass ich dich vergessen habe. Das Beispiel war bereits letzte Woche fertig, ich habe nur vergessen es dir zu schicken... Aus Faulheit hänge ich dir den gesamten Projektordner an, wo alles drin ist was du benötigst. Viel Spaß beim außeinandernehmen. Du hast von mir die persönliche Erlaubnis die angegebene Lizenz (LGPL) zu ändern und alle Copyrighthinweise zu entfernen. Ich habe sie nur drin gelassen, weil ich meinen Editor standardmäßig dazu angewiesen habe, sie in neue PHP-Dateien mit aufzunehmen. Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Ne, ne. Die bleiben schön drinne, fals ich es außerhalb meines privaten Bereichs veröffentlichen sollte.
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Zitat:
vielleicht verwirrt das drumherum in meiner Ordnerstruktur etwas. Der eigentliche Beispielcode befindet sich in der debug.php. Hier habe ich rumgespielt bis es lief wie es sollte. Wie man das Beispiel genau anwendet erkläre ich gleich. Neu ist noch die Trennung von Projekt ("app(lication)") und Framework ("lib"). Ersteres beinhaltet alles spezifische für dein Projekt. Letzteres ist allgemein gehalten und sollte bei einem vollständigem Framework ohne jegliche Änderung in jedes andere Projekt übernommen werden können. Quasi die VCL, wenn ich das als nicht-Delphianer richtig verstanden habe. ;-) Außerdem neu ist der Autoloader. Der besteht aus einer einfachen Funktion, dessen Name __autoload sein muss. Diese wird immer dann aufgerufen, wenn auf einen Klassen-Namen zugegriffen wird, der nicht existiert. Diese wird als Parameter an die Funktion übergeben. Die Aufgabe der Funktion ist es, diese Klasse zu laden. Das klappt nur dann, wenn der Name der Klasse einem Schema folgt. Dazu erstellt man zwei Pfade für Projektdateien (lib und app eben), in denen automatisch gesucht wird, wenn man require bzw. include benutzt. Ein Unterstrich im Klassennamen repräsentiert einen untergeordneten Ordner. Somit wird nach Meine_tolle_Klasse in /lib/Meine/tolle/Klasse.php und in /app/Meine/tolle/Klasse.php gesucht. Das ist nützlich, damit man sich so die ganzen includes spart und gezwungen ist, seine Klassen sinnvoll zu benennen. Sinnvoll ist hierbei, Framework und App jeweils einen Präfix zu geben. Heißt das Framework der DP beispielsweise "Asdf", so heißt eine Klasse im Framework zum Beispiel Asdf_Db_Table. Eine Klasse des Projekts dann DP_Form_NewAddress. Ich persönliche liebe diesen Autoloader und würde nicht mehr ohne in PHP arbeiten. Vielleicht teilst du diese Idee mit mir. ;-) Zurück zu den Forms: Eigentlich kannst du die Klassen so anwenden wie ich es beschrieben habe. Du überprüfst also zuerst, ob bereits ein Formular angesendet wurde. Das macht man am besten indem man schaut ob GET oder POST verwendet wurde. Anschließend erstellst du eine Instanz des speziellen Formulars. Je nach HTTP-Methode übergibst du entweder die Daten an das Formular (
PHP-Quellcode:
) oder lässt das Formular leer (
$form = new MeineApp_Form_NewAddess($_POST);
PHP-Quellcode:
). Falls du Daten übergeben hast, prüfst du, ob die Daten im Formular valide sind. Sind sie es, führst du entsprechende Schritte aus (Eintrag in DB) und leitest auf eine Bestätigungsseite weiter. Sind sie es nicht, oder wurde das Formular noch nicht ausgefüllt, übergibst du das Formular an ein View (Du brauchst sowas!) und lässt es (ggf. erneut) anzeigen. Im Ganzen sieht das dann etwa so aus:
$form = new MeineApp_Form_NewAddess();
PHP-Quellcode:
Die letzte Zeile, also die Übergabe des Formulars an das View macht hier mehr als man denkt. Das View ist in diesem Fall eine Eigenschaft des Controllers, die automatisch vor dem Aufruf des Controllers erstellt wird. So mache ich und die meisten Frameworks das immer. Nach dem Aufruf des Controllers wird (falls es keinen Fehler und keinen Redirect gab) das View aufgerufen. Der Hauptcode des Projekte sollte also etwa so aussehen:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$form = new MeineApp_Form_NewAddess($_POST); if ($form->is_valid()) { $address = new MeineApp_Model_Address($form->cleaned_data); $address->save(); // redirect("/thanks/"); } } else { $form = new MeineApp_Form_NewAddess(); } $this->view->form = $form;
PHP-Quellcode:
Nach Ausführung der Hauptmethode des Controllers sollte das View das Formular rendern. Hier gilt in etwa folgendes Vorgehen:
$controller = get_the_right_controller_instance_from_url();
$controller->pre_exec(); // erstellt View $controller->exec(); // führt den Controller aus $controller->post_exec(); // lässt das View rendern
PHP-Quellcode:
Das View kann man auf verschiedene Weisen machen, zum Beispiel über eine Template Engine wie Smarty. Ich mag diese Engines aber nicht, da ich keinen Vorteil in Ihnen sehe und sie langsamer sind als nötig. Ich realisieren Views immer als HTML-PHP-Gemisch-Dateien. Das View würde also zum Beispiel sowas machen:
public function post_exec() {
echo $this->view->render(); }
PHP-Quellcode:
Man sieht deutlich, dass die einzelnen Teile des Formulars zwar vom View zusammengesetzt werden, die Formularfelder aber vom Formular selbst erstellt werden. Diese Trennung macht die Sache sehr flexibel. Das Formular selbst weiß am besten welche Datentypen die Felder haben und ob etwas im Feld drin steht, oder ob es leer ist. Diese Arbeit gehört nicht in das View und wird so besonders gut getrennt.
<h1><? echo $this->headline; </h1>
<form action="/a/s/d/f" method="post"> <? echo $this->form->fields['name']->render(); ?> <span class="error"><? echo $this->form->fields['name']->errors; ?></span> </form> So, genug Lese- und Lernstoff für die nächste Zeit, oder? ;-) Ich hoffe es ist etwas klarer. Gern kann ich auch rudimentär ein Beispiel für die Controller und Views machen, da mir das doch ziemlich Spaß macht. Ich würde behaupten, sobald du diese Vorgehensweisen verstanden hast und sie anwenden kannst, kannst du professionell mit PHP Webseiten entwickeln. Also lass dich nicht entmutigen. Einfach irgendwas zusammenfriemeln kann jeder. :zwinker: Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Besten Dank. ja, wo ich was ändern muss, damit es bei mir läuft habe ich schon rausgefunden und was die debug.php macht.
Ich werde mal sehen, ob ich damit klar komme. Jedenfalls habe ich schon viel gelernt. |
AW: [PHP] Klassenstruktur für Adressdatenbank
Da stimmt aber irgendwas nicht:
Code:
Ich habe nur folgendes gemacht:
Warning: include(MeineApp/Form/Address.php): failed to open stream: No such file or directory in /var/www/l3s11195/html/Admin/luckie/debug.php on line 27 Warning: include(MeineApp/Form/Address.php): failed to open stream: No such file or directory in /var/www/l3s11195/html/Admin/luckie/debug.php on line 27 Warning: include(): Failed opening 'MeineApp/Form/Address.php' for inclusion (include_path='.:/usr/share/php:app/:lib/') in /var/www/l3s11195/html/Admin/luckie/debug.php on line 27 Fatal error: Uncaught exception 'Exception' with message 'Cannot load class MeineApp_Form_Address from MeineApp/Form/Address.php' in /var/www/l3s11195/html/Admin/luckie/debug.php:29 Stack trace: #0 /var/www/l3s11195/html/Admin/luckie/debug.php(58): __autoload('MeineApp_Form_A...') #1 {main} thrown in /var/www/l3s11195/html/Admin/luckie/debug.php on line 29
PHP-Quellcode:
/* $form = new MeineApp_Form_Irgendwas(array(
'vorname' => "Valentin", 'name' => "Voigt", 'priv_email1' => "mail@..." )); if ($form->is_valid()) { $a = new MeineApp_Model_Address($form->cleaned_data); $a->save(); } else { // ans View übergeben foreach ($form->fields as $field) echo implode("\n", $field->errors); }*/ if ($_SERVER['REQUEST_METHOD'] == 'POST') { $form = new MeineApp_Form_Address($_POST); if ($form->is_valid()) { $address = new MeineApp_Model_Address($form->cleaned_data); $address->save(); // redirect("/thanks/"); } } else { $form = new MeineApp_Form_Address(); } $this->view->form = $form; |
AW: [PHP] Klassenstruktur für Adressdatenbank
Du hast den include_path nicht gesetzt. Lies doch die Fehlermeldung.
Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Di ahbe ich ja gelesen. Nur dachte ich das hätte ich gemacht, Deswegen werde ich ja nicht so ganz schlau aus der fehlermeldung:
PHP-Quellcode:
Bevor ich das mit der Form eingefügt hatte hat es ja funktioniert.
set_include_path(get_include_path() . PATH_SEPARATOR . "app/");
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/"); |
AW: [PHP] Klassenstruktur für Adressdatenbank
Ups, jetzt habe ich geschlafen. Es hat funktioniert, weil keine nicht-existierende Klasse verwendet wurde. Schau doch mal ob die gesuchte Datei "Address.php" im angegebenen Ordner denn wirklich existiert. Außerdem bietet es sich an im include_path absolute Pfade zu verwenden.
Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
OK, bin ein Stück weiter:
Code:
Aber die Datei existiert an der Stelle und auch die Klasse in der Datei. Das macht mich etwas ratlos.
Fatal error: Uncaught exception 'Exception' with message 'Cannot load class MeineApp_Form_Address from MeineApp/Form/Address.php' in /var/www/l3s11195/html/Admin/luckie/debug.php:29 Stack trace: #0 /var/www/l3s11195/html/Admin/luckie/debug.php(58): __autoload('MeineApp_Form_A...') #1 {main} thrown in /var/www/l3s11195/html/Admin/luckie/debug.php on line 29
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Das habe ich schon vermutet. ^^
Du musst die Klasse selbst auch umbenennen. Versuche nochmal genauer zu überlegen wie der Autoloader funktioniert. Er hat eine ganze Menge an tollen Vorteilen, zB. eben dass die Klassen im richtigen Schema benannt werden müssen. Und dass nur eine Klasse pro Datei möglich ist. Anhand des Dateipfades einer Datei kann man den Klassennamen bestimmen und umgekehrt. :-) Liebe Grüße, Valentn |
AW: [PHP] Klassenstruktur für Adressdatenbank
Ja, diese clevere Idee habe ich schon verstanden.
Also ich habe jetzt:
PHP-Quellcode:
Und die Datei MeineApp/Form/Address.php gibt es mit der Klasse
$form = new MeineApp_Form_Address
PHP-Quellcode:
. So war es doch gedacht oder?
class Address extends Form
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Nicht ganz. Denke an meinen letzten Satz. Klassenname und Dateipfad sind austauschbar. In deinem Namen fehlt quasi der Pfad. Du siehst doch selbst, dass du die Klasse MeineApp_Form_Address benutzen willst, aber deine Klasse nur Address heißt. ;-)
Bettzeit! ;-) Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Sag mal, fehlt die View-Klasse nicht noch irgendwo?
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Ja. Natürlich. Deswegen hab ich ja noch angeboten das auch noch zu machen.
Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Ja, dann nehme ich das Angebot doch mal an. ;) Nur um eine Idee zu bekommen, wie das aussieht.
|
AW: [PHP] Klassenstruktur für Adressdatenbank
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Luckie,
ich habe jeztt Views, Controller, Routing und Exception Handling für dich. Im Framework wurden einige Stellen geändert. Die genauen Änderungen kannst du sicher selbst über ein diff-Programm herausfinden. Ich könnte jetzt seitenweise Sachen erklären und schreiben, aber ich fasse mich kurz. Das Routing läuft jetzt anders als du es gewohnt bist. Eine Erklärung habe ich vor 2 Jahren in meinem Blog veröffentlicht. Diese weicht etwas ab von meiner Implementation heute, im Grundsatz ist das aber das gleiche. :) Die Klassen sind alle sehr kurz und einfach gehalten. Der Quellcode enthält wenig Kommentare, da ich versuche meinen Code so zu schreiben, dass keine Kommentare benötigt werden. Vielleicht arbeitest du dich von "public/index.php" einfach mal durch. In dieser Datei musst du vorher deine MySQL Verbindungsdaten eintragen, außerdem dem absoluten Pfad zum Projektverzeichnis (APPDIR). Stell ruhig Fragen wenn welche entstehen! :-) Außerdem musst du den URL Präfix ändern. Das ist der Teil vor der URL, der entsteht, wenn diese Webseite nicht direkt unter "/" läuft. Hast du also alles im Ordner "/projects/luckie", dann ist der Präfix "/projects/luckie". Alles was nach dem Präfix kommt ist ja die tatsächliche URL in der Webanwendung. Unter "/projects/luckie/kunde/21" versteht sich ja eigentlich "/kunde/21", daher der Präfix. Wenn das nicht benötigt wird, dann setze den URL Präfix (Die Konstante heißt APPURI) einfach auf Leerstring. Hoffe das ist klar. Ich find's klasse dass du dir das alles antust. :thumb: Liebe Grüße, Valentin |
AW: [PHP] Klassenstruktur für Adressdatenbank
Zitat:
Code:
Wobei das Ausrufezeichen bedeutet, dass an der Stelle kein leerer Ausdruck zugelassen ist.
PrettyUrlParser::$mappings = array(
'blog/tags/{tag}/{page!}' => 'BlogOverview', 'blog/tags/{tag}' => 'BlogOverview', 'blog/page/{page!}' => 'BlogOverview', 'blog/' => 'BlogOverview', 'blog' => 'BlogOverview', 'blog/{id}-{name!}' => 'BlogSingle', 'blog/{id}' => 'BlogSingle' ); Einen Vorteil hat das ganze allerdings, nämlich funktioniert das ganze auch sehr leicht rückwärts – ich kann einfach ein Parameter=>Wert-Array automatisch in die dafür konfigurierte URL umwandeln. Wobei das mit der benannten Regex-Syntax sicherlich auch ginge, nur wäre der Parser dann wohl etwas komplexer... Fazit: Immer wieder schön zu sehen, dass es verschiedene Wege gibt, die zum Ziel führen :wink: |
AW: [PHP] Klassenstruktur für Adressdatenbank
Ui, da muss ich mich jetzt aber mal durchwuseln.Und ich wollte doch nur meine private Adressdatenbank etwas aufhübschen im Code. ;)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz