Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [PHP] Klassenstruktur für Adressdatenbank (https://www.delphipraxis.net/166235-%5Bphp%5D-klassenstruktur-fuer-adressdatenbank.html)

Luckie 6. Mär 2012 17:47

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Ja, das dass Unsinn ist, war klar.

Ich habe es jetzt so:
PHP-Quellcode:
case "save":
               $adressen = new DB_Adressen();
               $adressen->name = $name;
               $adressen->vorname = $vorname;
               $adressen->save();            
               break;
Und das kommt auch an. Nur wie kann ich jetzt unterscheiden, ob es ein neuer Datensatz ist oder ob ein existierender bearbeitet wurde?

Valle 6. Mär 2012 17:53

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

Luckie 6. Mär 2012 18:04

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.

Valle 6. Mär 2012 18:24

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Zitat:

Zitat von Luckie (Beitrag 1154837)
Das heißt, wenn ich das Form mit Daten eines schon existierenden Datensatzes fülle wird der Flag automatisch gesetzt?

Ich bin mir nicht sicher wie du das meinst, aber ich denke das ist nicht richtig.

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:
$person = new DB_Adresse(array(), true);
$person->id = 42;
$person->email = "muster@example.com";
$person->save(); // UPDATE
An ein genaueres Beispiel werd' ich mich dann heut Abend machen. :)

Liebe Grüße,
Valentin

Luckie 6. Mär 2012 19:05

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Danke, aber ich werde wahrscheinlich erst am Sonntag wieder dazu kommen, an dem Projekt weiterzuarbeiten.

Valle 21. Mär 2012 20:35

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

Luckie 21. Mär 2012 21:06

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Ne, ne. Die bleiben schön drinne, fals ich es außerhalb meines privaten Bereichs veröffentlichen sollte.

Valle 22. Mär 2012 17:04

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Zitat:

Zitat von Luckie
Hallo valle,
vielen Dank für deine Mühe.

Ich habe es jetzt mit meiner Datenbank zum Laufen gebracht. Aber wie erstelle ich ein neues leeres Formular und wie bekomme ich einen Datensatz zum Ändern angezeigt und wie kann ich einen Datensatz suchen? Da bin ich noch nicht so richtig durchgestiegen, wie das funktioniert.

Ich hoffe es ist in Ordnung dass ich hier im Thread auf deine Frage in der PM antworte. Das Zeichenlimit für die PM habe ich leider überschritten und ich denke jeder sollte etwas davon haben. ;-)

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:
$form = new MeineApp_Form_NewAddess($_POST);
) oder lässt das Formular leer (
PHP-Quellcode:
$form = new MeineApp_Form_NewAddess();
). 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:

PHP-Quellcode:
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;
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:

PHP-Quellcode:
$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
Nach Ausführung der Hauptmethode des Controllers sollte das View das Formular rendern. Hier gilt in etwa folgendes Vorgehen:

PHP-Quellcode:
public function post_exec() {
    echo $this->view->render();
}
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:

PHP-Quellcode:
<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>
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.

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

Luckie 22. Mär 2012 17:22

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.

Luckie 22. Mär 2012 19:02

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Da stimmt aber irgendwas nicht:
Code:
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
Ich habe nur folgendes gemacht:
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;

Valle 22. Mär 2012 19:26

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Du hast den include_path nicht gesetzt. Lies doch die Fehlermeldung.

Liebe Grüße,
Valentin

Luckie 22. Mär 2012 20:03

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:
set_include_path(get_include_path() . PATH_SEPARATOR . "app/");
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/");
Bevor ich das mit der Form eingefügt hatte hat es ja funktioniert.

Valle 22. Mär 2012 20:07

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

Luckie 22. Mär 2012 20:28

AW: [PHP] Klassenstruktur für Adressdatenbank
 
OK, bin ein Stück weiter:
Code:
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
Aber die Datei existiert an der Stelle und auch die Klasse in der Datei. Das macht mich etwas ratlos.

Valle 22. Mär 2012 20:35

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

Luckie 22. Mär 2012 20:48

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Ja, diese clevere Idee habe ich schon verstanden.

Also ich habe jetzt:
PHP-Quellcode:
$form = new MeineApp_Form_Address
Und die Datei MeineApp/Form/Address.php gibt es mit der Klasse
PHP-Quellcode:
class Address extends Form
. So war es doch gedacht oder?

Valle 22. Mär 2012 20:50

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

Luckie 22. Mär 2012 21:14

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Sag mal, fehlt die View-Klasse nicht noch irgendwo?

Valle 23. Mär 2012 05:29

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Ja. Natürlich. Deswegen hab ich ja noch angeboten das auch noch zu machen.

Liebe Grüße,
Valentin

Luckie 23. Mär 2012 07:17

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Ja, dann nehme ich das Angebot doch mal an. ;) Nur um eine Idee zu bekommen, wie das aussieht.

Valle 23. Mär 2012 23:49

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

Namenloser 24. Mär 2012 01:01

AW: [PHP] Klassenstruktur für Adressdatenbank
 
Zitat:

Zitat von Valle (Beitrag 1158247)
Das Routing läuft jetzt anders als du es gewohnt bist. Eine Erklärung habe ich vor 2 Jahren in meinem Blog veröffentlicht.

So ähnlich mache ich es in dem kleinen CMS, das ich schreibe, auch. Allerdings bin ich gar nicht drauf gekommen, dass man direkt benannte Sub-Patterns für die Parameter-Zuordnung verwenden kann. Was ich bisher mache, ist etwas komplizierter; und zwar habe ich eine eigene kleine Syntax entworfen, die dann in PREG „kompiliert“ wird. Ein Mapping sieht in dieser Syntax z.B. so aus:
Code:
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'
);
Wobei das Ausrufezeichen bedeutet, dass an der Stelle kein leerer Ausdruck zugelassen ist.

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:

Luckie 24. Mär 2012 01:59

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.
Seite 2 von 2     12   

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