== Erläuterung ==
Der Code ist zur Hilfenahme entstanden, als die Frage geklärt werden sollte ob man die Validierung im Controller oder im Model praktizieren sollte: Überprüfung von Werten in $_POST Feldern. Mehr Informationen zum Basismodel sollen noch folgen. Jeder ist aber angehalten den Artikel zu verbessern.
Das hier erläutere Verfahren nutzt object-relational mapping bzw Objektrelationale Abbildung - kurz ORM.
== Basismodel ==
Alles anzeigen
== Beispielimplementierung eines Benutzers ==
Alles anzeigen
== Beispiele ==
=== Neuen Benutzer anlegen ===
Alles anzeigen
=== Benutzer bearbeiten ===
Alles anzeigen
Der Code ist zur Hilfenahme entstanden, als die Frage geklärt werden sollte ob man die Validierung im Controller oder im Model praktizieren sollte: Überprüfung von Werten in $_POST Feldern. Mehr Informationen zum Basismodel sollen noch folgen. Jeder ist aber angehalten den Artikel zu verbessern.
Das hier erläutere Verfahren nutzt object-relational mapping bzw Objektrelationale Abbildung - kurz ORM.
== Basismodel ==
Quellcode
- abstract class Model {
- protected $primarykey = 'id';
- protected $data = array();
- abstract public function getColumns();
- function __construct($data = array()) {
- $this->data = $data;
- }
- public static function findById($id, $className) {
- $sql = "SELECT *
- FROM ".$this->getTablename()."
- WHERE ".$this->primarykey." = :id ";
- $stmt = MyDB::getInstance()->prepare($sql);
- $stmt->execute(array(
- ':id' => $id
- ));
- return new $className($stmt->fetch());
- }
- protected function _findById() {
- }
- public function __set($name, $value) {
- $this->data[$name] = $value;
- }
- public function __get($name) {
- return $this->data[$name];
- }
- /**
- * empty() on a __get function will not work as expected if isset has not been overriden
- */
- public function __isset($key) {
- if (isset($this->data[$key])) {
- return (false === empty($this->data[$key]));
- } else {
- return null;
- }
- }
- public function validate() {
- }
- public function getTablename() {
- return get_class($this);
- }
- public function delete() {
- $primaryval = $this->{$this->primarykey};
- $sql = 'DELETE FROM '.$this->getTablename().' WHERE '.$this->primarykey.' = :primaryval';
- $stmt = MyDB::getInstance()->prepare($sql);
- $stmt->execute(array(
- ':primaryval' => $primaryval
- ));
- }
- public function save($override = null) {
- if($override !== null) {
- $this->data = array_merge($this->data, $override);
- }
- $this->validate();
- $params = array();
- $primaryval = $this->{$this->primarykey};
- // insert or update
- if($primaryval === null) {
- $sql = 'INSERT INTO '.$this->getTablename().' ('.implode(',', $this->getColumns()).') VALUES (';
- foreach($this->getColumns() as $key) {
- $sql .= ':'.$key.',';
- $params[':'.$key] = $this->$key;
- }
- $sql = rtrim($sql,',').')';
- if(count($params)) {
- $stmt = MyDB::getInstance()->prepare($sql);
- $stmt->execute($params);
- // remember auto increment key
- $this->{$this->primarykey} = MyDB::getInstance()->lastInsertId();
- }
- } else {
- $sql = 'UPDATE '.$this->getTablename().' SET ';
- foreach($this->getColumns() as $key) {
- $sql .= $key.' = :'.$key.',';
- $params[':'.$key] = $this->$key;
- }
- $sql = rtrim($sql,',').' WHERE '.$this->primarykey.' = :primaryval';
- if(count($params)) {
- $params[':primaryval'] = $primaryval;
- $stmt = MyDB::getInstance()->prepare($sql);
- $stmt->execute($params);
- }
- }
- }
- }
== Beispielimplementierung eines Benutzers ==
Quellcode
== Beispiele ==
=== Neuen Benutzer anlegen ===
Quellcode
=== Benutzer bearbeiten ===
Quellcode
- <form method="post" action="edit.php?userid=123">
- email: <input type="text" name="email" /><br/>
- password: <input type="password" name="password" /><br/>
- <input type="submit">
- </form>
- <?php
- if(count($_POST) && isset($_GET['userid'])) {
- $user = User::findById($_GET['userid']);
- $user->save($_POST);
- }
- ?>
8.209 mal gelesen
vince -
Was ich ein bischen unschön finde ist, das der Konstruktor das gesamte Post Array entgegennimmt / entgegennehmen kann.
[syntax="php"]$user = new User($_POST);[/syntax]
Das ist natürlich sehr einfach und praktisch, aber wird später sehr unübersichtlich.
Man selber und vorallem auch andere wissen nicht, welche Felder es denn überhaupt gibt und was required ist oder was selber von dem Model intern ggf. übernommen wird.
Um das zu wissen müsste man immer in die Datenbank gucken, welche Felder es gibt und wie diese heissen und dann nochmal in die Klasse schauen falls es noch weitere interne Verarbeitungen gibt.
Ich finde die längere Variante, alles einzeln über den Konstruktor zu setzen und / oder für alle einen Getter & Setter zu implementieren, vorallem hinsichtlich der Lesbarkeit & Wiederverwendbarkeit , schöner.
Zum Beispiel Doctrine nutzt die magischen Getter & Setter, setzt aber als ausgleich alle Felder als Kommentar, so das die IDE´s das bei, Autocomplete trotzdem alles sauber anzeigen.
Aber ansonsten wieder ein schöner Artikel