Ergebnis 1 bis 2 von 2

Thema: Abstrakte Klasse: Mysqli_Entity

  1. #1
    Großmeister(in)
    Registriert seit
    09.12.2008
    Ort
    Berlin
    Alter
    38
    Beiträge
    666
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings
    Blog-Einträge
    1

    Standard Abstrakte Klasse: Mysqli_Entity

    Hinweis vorweg:
    Ich habe mir diese Klasse für kleinere private Projekte geschrieben, für die ich kein ORM nutze. Sie ist auf meine persönlichen Vorlieben beim Entwickeln abgestimmt. An einigen Stellen lässt sie den Kindklassen durch Sichtbarkeit protected (bzw. den Objekten einer Kindklasse durch Sichtbarkeit public) genug Spielraum um Funktionalitäten zu zerschießen.
    Das ist mir bequßt und ich nehme das aus Gründen der Komfortabilität beim Coden in Kauf. Wer auch immer diese Klasse verwenden möchte muss selber darauf achten, beim direkten Schreiben von protected-Eigenschaften aus einer Kindklasse heraus die Werte angemessen zu prüfen.
    Falls gewünscht kann ich bei Gelegenheit auch noch ein Beispiel zur Verwendung posten.
    __________________________________________________ ____


    Bei der Mysqli_Entity handelt es sich um eine abstrakte Klasse, die Standardfunktionen wie getter, setter, load, save, delete für Klassen bereitstellt, die eine Entitäten-Tabelle abbilden.
    Eine konkrete Klasse die von Mysqli_Entity erbt kann die nötigen Informationen für die Datenbank-Operationen (Mysqli-Objekt, Tabellenname, Felder, PrimaryKey-Informationen etc.) an die Elternklasse Mysqli_Entity übergeben und anfallende Datenbank-Operationen komfortabel an diese delegieren.
    Sämtliche Werte werden von Mysqli_Entity vor dem Eintragen in die Datenbank mit real_escape_string behandelt, und nach dem Auslesen mit stripslashes.
    Backticks `` um Tabellen- und Feldnamen werden von Mysqli_Entity ebenfalls automatisch gesetzt, sollten also bei Übergabe der entsprechenden Werte von der Tochterklasse nicht gesetzt werden.

    Mysqli_Entity stellt folgende Eigenschaften und Methoden bereit (kompletter Code im zweiten Post):
    PHP-Code:
    abstract class Mysqli_Entity {
        private 
    $loadPropertyOnDemand false;
        private 
    $autosave false;
        private 
    $isUpdated false;

        protected 
    $db null;
        protected 
    $table null;
        protected 
    $pkField null;
        protected 
    $pkValue false;
        protected 
    $properties = array();
        protected 
    $data = array();

        protected function 
    setup(mysqli $db,$table,$pkValue=false) {}
        protected function 
    addProperty($property) {}
        protected function 
    setAutosave($autosave=true) {}
        protected function 
    loadPropertyOnDemand($loadPropertyOnDemand=true) {}
        protected function 
    loadSchemeFromTable() {}

        public function 
    setPrimaryKey($value) {}
        public function 
    getProperty($property) {}
        public function 
    setProperty($property,$value) {}
        public function 
    load() {}
        public function 
    save() {}
        public function 
    delete() {}
        public function 
    __destruct() {}

        private function 
    checkTableInfo($checkPrimaryKey=true) {}

    Die Eigenschaften und Methoden im Einzelnen:

    Eigenschaften:
    private $loadPropertyOnDemand = false;
    Mit dieser Eigenschaft wird festgelegt, ob der Inhalt einer property bei Anforderung automatisch geladen werden soll, wenn dieser noch nicht gesetzt ist.
    Default ist false, dies kann über die Methode loadPropertyOnDemand() geändert werden.

    private $autosave = false;
    Mit dieser Eigenschaft wird festgelegt, ob Änderungen an Objekt-Eigenschaften beim zerstören des Objektes automatisch gespeichert werden sollen. Mit dieser Eigenschaft auf true braucht die save()-Methode also nicht mehr explizit aufgerufen werden.
    Default ist false, dies kann über die Methode autosave() geändert werden.

    private $isUpdated = false;
    Diese Eigenschaft wird nur intern verwendet um beim Aufruf der save()-Methode zu prüfen, ob Eigenschaften geändert wurden und ein UPDATE der Tabellenzeile nötig ist.

    protected $db = null;
    In dieser Eigenschaft wird das Mysqli-Objekt abgelegt. Dies kann entweder über eine direkte Zuweisung in der Tochterklasse geschehen, oder als Parameter an die Methode setup() übergeben werden.

    protected $table = null;
    In dieser Eigenschaft wird der Name der Tabelle abgelegt, von der das Objekt eine Zeile abbilden soll. Kann entweder über eine direkte Zuweisung in der Tochterklasse geschehen, oder als Parameter an die Methode setup() übergeben werden.

    protected $pkField = null;
    In dieser Eigenschaft wird der Feldname des PrimaryKeys der Tabelle abgelegt. Kann entweder über eine direkte Zuweisung in der Tochterklasse geschehen, oder über die Methode loadSchemeFromTable() (bzw. über die Methode setup() in welcher loadSchemeFromTable() aufgerufen wird) automatisch ermittelt werden.

    protected $pkValue = false;
    In dieser Eigenschaft wird der PrimaryKey-Wert der konkreten Tabellenzeile hinterlegt, die von dem Objekt abgebildet wird. Kann entweder über eine direkte Zuweisung in der Tochterklasse geschehen, oder als (optionaler) Parameter an die Methode setup() übergeben werden, oder explizit über die Methode setPrimaryKey() gesetzt werden.
    Wird der Wert in der Tochterklasse direkt zugewiesen, so ist zu beachten, dass sich die Tochterklasse vorher selber um ein ausreichendes escapen des Wertes kümmern muss, sofern dieser vom Client kommt.

    protected $properties = array();
    In dieser Eigenschaften werden die Feldnamen der Objekteigenschaften hinterlegt (nicht die Werte). Der Array kann automatisch über die Methoden loadSchemeFromTable() (bzw. indirekt über die Methode setup(), welche loadSchemeFromTable() aufruft) gefüllt werden.
    Alternativ (wenn nicht alle Felder der Tabelle verfügbar sein sollen) kann er manuell über die Methode addProperty() gefüllt werden. Hierbei ist zu beachten, dass die übergebenen Properties exakt den Spaltennamen der Tabelle entsprechen müssen (ohne Backticks ``, diese werden von der Klasse Mysqli_Entity automatisch ergänzt).

    protected $data = array();
    In dieser Eigenschaften werden die Werte der Properties hinterlegt. Der Array kann entweder automatisch über Aufruf der Methode load() aus der Datenbank gefüllt werden (mit allen Properties die zu diesem Zeitpunkt gesetzt sind) oder manuell über die Methode setProperty($property,$value).

    Methoden:
    protected function setup(mysqli $db,$table,$pkValue=false) {}
    Über diese Methode können alle relevanten Informationen für Datenbank-Operationen gesetzt werden. Der PrimaryKey $pkValue ist hierbei ein optionaler Parameter, um das Einfügen neuer Zeilen in die Tabelle zu ermöglichen.
    Diese Methode ruft die Methode loadSchemeFromTable() auf, in welcher der properties-Array automatisch mit allen Feldern der übergebenen Tabelle gefüllt wird.

    protected function addProperty($property) {}
    Mit dieser Methode können Properties zum properties-Array hinzugefügt werden. Wird nicht benötigt wenn dieser automatisch über Aufruf der Methode loadSchemeFromTable() (bzw. setup()) gefüllt wird.

    protected function setAutosave($autosave=true) {}
    Setter-Methode für die private Eigenschaft $autosave.

    protected function loadPropertyOnDemand($loadPropertyOnDemand=true) {}
    Setter-Methode für die private Eigenschaft $loadPropertyOnDemand.

    protected function loadSchemeFromTable() {}
    Diese Methode holt sich das Tabellenschema von der Datenbank und befüllt den $properties-Array mit allen Feldern der Tabelle. Ermittelt und setzt außerdem den Namen des Feldes, das als PrimaryKey fungiert.

    public function setPrimaryKey($value) {}
    Über diese Methode kann der PrimaryKey-Wert gesetzt werden. Der übergebene Wert wird mir real_escape_string behandelt.

    public function getProperty($property) {}
    Liefert den Wert einer Property. Ist der Wert für die angeforderte Property noch nicht gesetzt und die Eigenschaft $loadPropertyOnDemand steht auf false, so wird eine Exception geschmissen.

    public function setProperty($property,$value) {}
    Mit dieser Methode kann man einer Property einen Wert zuweisen.

    public function load() {}
    Diese Methode läd alle Property-Werte für das aktuelle Objekt in den $data-Array.

    public function save() {}
    Diese Methode speichert alle getätigten Änderungen. Wenn die Eigenschaft $autosave auf true steht wird diese Methode in __destruct() automatisch aufgerufen.

    public function delete() {}
    Löscht das aktuelle Objekt aus der Datenbank.

    public function __destruct() {}
    Magische Methode, wird automatisch vor dem Zerstören des Objektes aufgerufen. Prüft ob $autosave und $isUpdated auf true stehen und speichert gegebenenfalls alle getätigten Änderungen.

    private function checkTableInfo($checkPrimaryKey=true) {}
    Interne Methode die vor jeder Datenbank-Operation prüft, ob alle relevanten Eigenschaften gesetzt sind ($db, $table, $pkField, gegebenenfalls $pkValue)



    Kompletter Code:
    PHP-Code:
    abstract class Mysqli_Entity {
        private 
    $loadPropertyOnDemand false;
        private 
    $autosave                            false;
        protected 
    $db                                    null;
        protected 
    $table                            null;
        protected 
    $pkField                        null;
        protected 
    $pkValue                        false;
        protected 
    $properties                    = array();
        protected 
    $data                                = array();
        protected 
    $isUpdated                    false;

        protected function 
    setup(mysqli $db,$table,$pkValue=false) {
            if(!
    is_string($table)) {
                throw new 
    Exception("\$table has to be of type string.");
            }
            
    $this->db      $db;
            
    $this->table $this->db->real_escape_string($table);
            
    $this->loadSchemeFromTable();
            if(
    $pkValue!==false) {
                
    $this->setPrimaryKey($pkValue);
            }
        }
        protected function 
    addProperty($property) {
            if(!
    in_array($property,$this->properties)) {
                
    $this->properties[] = $property;
            }
        }
        protected function 
    setAutosave($autosave=true) {
            
    $this->autosave $autosave;
        }
        protected function 
    loadPropertyOnDemand($loadPropertyOnDemand=true) {
            
    $this->loadPropertyOnDemand $loadPropertyOnDemand;
        }
        protected function 
    loadSchemeFromTable() {
            
    $this->checkTableInfo(false);
            if(
    count($this->properties)) {
                
    $this->properties = array();
            }
            
    $pkCount 0;
            
    $sql "DESCRIBE `{$this->table}`";
            
    $res $this->db->query($sql);
            while(
    $row $res->fetch_assoc()) {
                
    $this->properties[] = $row['Field'];
                if(
    $row['Key']==="PRI") {
                    if(
    $pkCount>0) {
                        throw new 
    Exception("Class Mysqli_Entity does not support tables with composite primary keys.");
                    }
                    
    $this->pkField $row['Field'];
                    
    $pkCount++;
                }
            }
            if(
    $pkCount===0) {
                throw new 
    Exception("No Primary Key defined for table `{$this->table}`");
            }
        }
        public function 
    setPrimaryKey($value) {
            
    $this->pkValue = (int)$value;
        }
        public function 
    getProperty($property) {
            if(!
    in_array($property$this->properties)) {
                throw new 
    Exception("Property {$property} does not exist.");
            }
            if(!
    array_key_exists($property,$this->data) && $this->loadPropertyOnDemand===false) {
                throw new 
    Exception("No value available for Property {$property}.",10);
            }
            elseif(!
    array_key_exists($property,$this->data) && $this->loadPropertyOnDemand!==false) {
                
    $this->checkTableInfo();
                
    $sql "SELECT `{$property}` FROM `{$this->table}` WHERE `{$this->pkField}`='{$this->pkValue}'";
                
    $res $this->db->query($sql);
                
    $row $res->fetch_row();
                if(
    $row===null) {
                    throw new 
    Exception("Property {$property} could not be retrieved from database.",20);
                }
                
    $res->close();
                unset(
    $res);
                
    $this->data[$property] = stripslashes($row[0]);
                unset(
    $row);
            }
            return 
    $this->data[$property];
        }
        public function 
    setProperty($property,$value) {
            if(!
    in_array($property,$this->properties)) {
                throw new 
    Exception("Property {$property} does not exist.");
            }
            elseif(!isset(
    $this->data[$property]) || $value!=$this->data[$property]) {
                
    $this->data[$property] = $value;
                
    $this->isUpdated true;
            }
        }
        public function 
    load() {
            
    $this->checkTableInfo();
            if(
    count($this->properties)===0) {
                throw new 
    Exception("No properties defined.");
            }
            
    $properties implode("`,`",$this->properties);
            
    $sql "SELECT `{$properties}` FROM `{$this->table}` WHERE `{$this->pkField}`='{$this->pkValue}'";
            
    $res $this->db->query($sql);
            
    $row $res->fetch_assoc();
            if(
    $row===null) {
                throw new 
    Exception("Entity not found");
            }
            foreach(
    $row as $key=>$value) {
                
    $this->data[$key] = stripslashes($value);
            }
            
    $res->close();
            unset(
    $res);
            unset(
    $row);
            return 
    $this->data;
        }
        public function 
    save() {
            if(
    $this->isUpdated===false) {
                return;
            }
            
    $this->checkTableInfo(false);
            foreach(
    $this->data as $key=>$value) {
                
    $value $this->db->real_escape_string($value);
                
    $data[]    = "`{$key}`='{$value}'";
            }
            
    $data implode(",",$data);
            if(
    $this->pkValue!==false) {
                
    $sql "UPDATE `{$this->table}` SET {$data} WHERE `{$this->pkField}`='{$this->pkValue}'";
            }
            else {
                
    $sql "INSERT INTO `{$this->table}` SET {$data}";
            }
            
    $this->db->query($sql);
            if(!
    $this->db->affected_rows) {
                throw new 
    Exception("Object could not be saved.");
            }
            
    $this->isUpdated false;
            if(
    $this->pkValue===false && $this->db->insert_id) {
                
    $this->pkValue $this->db->insert_id;
                return 
    $this->pkValue;
            }
            return 
    true;
        }
        public function 
    delete() {
            
    $this->checkTableInfo();
            
    $sql "DELETE FROM `{$this->table}` WHERE `{$this->pkField}`='{$this->pkValue}'";
            
    $this->db->query($sql);
            return 
    $this->db->affected_rows;
        }
        private function 
    checkTableInfo($checkPrimaryKey=true) {
            if(!
    $this->db || !($this->db instanceof mysqli)) {
                throw new 
    Exception("Database-Object is not defined or not of type mysqli.");
            }
            elseif(!
    is_string($this->table)) {
                throw new 
    Exception("No table defined.");
            }
            if(
    $checkPrimaryKey!==false) {
                if(!
    is_string($this->pkField) || $this->pkValue===null) {
                    throw new 
    Exception("Primary Key is not defined.");
                }
            }
        }
        public function 
    __destruct() {
            if(
    $this->autosave && $this->isUpdated) {
                
    $this->save();
            }
        }

    Achtung: Dies ist ein alter Thread im HTML und Webmaster Forum
    Diese Diskussion ist älter als 90 Tage. Die darin enthaltenen Informationen sind möglicherweise nicht mehr aktuell. Erstelle bitte zu deiner Frage ein neues Thema im Forum !!!!!
    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  2. #2
    der/die Göttliche Avatar von jojo87
    Registriert seit
    23.03.2007
    Ort
    Leipzig
    Alter
    30
    Beiträge
    3.131
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard AW: Abstrakte Klasse: Mysqli_Entity

    sehr schön
    Für diejenigen, dies interessiert: Das ist eine klassische Umsetzung des Active-Record-Patterns, wie es Doctrine früher benutzt hat.
    Das nur zur Vollständigkeit, damit Nutzer auch in etwa wissen worauf sie sich einlassen.
    Mein erster und bisher einziger ORM-Mapping Versuch sah fast exakt genau so aus

Ähnliche Themen

  1. OOP Klasse
    Von Nico1994 im Forum PHP Forum - Apache - CGI - Perl - JavaScript und Co.
    Antworten: 3
    Letzter Beitrag: 13.09.2010, 18:50
  2. Kalender Klasse
    Von SinnlosS im Forum Script-Archiv
    Antworten: 9
    Letzter Beitrag: 02.06.2009, 11:16
  3. Klasse 9
    Von im Forum Off Topic und Quasselbox
    Antworten: 2
    Letzter Beitrag: 14.12.2007, 13:31
  4. grosse Klasse! :-)
    Von eatofid im Forum Forum-Hilfe.de intern
    Antworten: 6
    Letzter Beitrag: 10.11.2007, 13:44
  5. Online, Abstrakte Geschichts Spiel
    Von Loikaemie im Forum Das Forum für Spiele, Fun & Jokes
    Antworten: 0
    Letzter Beitrag: 24.11.2004, 12:36

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •