PHP: HTML-Formular -- Felder in Klassenvariable speichern
Die Eigenschaften und Regeln eines Feldes sind für alle Objekte einer Klasse dieselben. Statt diese identische Felder für jedes Objekt zu erzeugen werden sie einmalig in einer Klassenvariablen gespeichert.
class FieldModel { static protected $_fields = []; // $_fields['id'] = new IntegerField(... private $_accessors = []; // $_accessors['form_register_read'] = new Accessor(... private $_values = []; // Do not overwrite private $_devErrors = []; // $devErrors['id'][] = 'Error: ' private $_userErrors = []; ... class PersonModel extends FieldModel { ...
In static protected $_fields
sind die Felder wie IntegerField(),
TextField()
gespeichert.
Für die einzelnen Objekte der PersonModel
-Klasse sind die Werte
in der Objekt-Variable private $_values = []
gespeichert -- z.B. $_values['id'] = 42
.
Der Zugriff auf die Werte erfolgt über __get(), __set()
.
class PersonModel extends FieldModel { static protected $_fields = []; // $_fields['id'] = new IntegerField(... class EmployeeModel extends FieldModel {... static protected $_fields = []; // $_fields['salary'] = new IntegerField(... $john = new EmployeeModel(); echo $john->id;
__get()
schaut zunächst nach, ob $john->_values['id']
bereits vorhanden ist und gibt im Erfolgsfall den Wert zurück.
public function __get($name) { if(array_key_exists($name, $this->_values)) { return $this->_values[$name]; }
Falls das nicht der Fall ist, werden die Felder der Klasse EmployeeModel
und die der Elternklassen (PersonModel
, FieldModel
) nach einem
Field-Objekt für 'id'
durchsucht.
EmployeeModel::$_fields['salary']; PersonModel::$_fields['id', 'name', 'email']; FieldModel::$_fields[];
(static protected $_fields
muss deshalb in jeder abgeleiteten Klasse
deklariert sein, damit nach den Feldern direkt in der jeweiligen Klasse gesucht wird.)
Wird dieses gefunden, wird $john->_values['id']
auf den
defaultValue
des id-Feldes
gesetzt und der Wert zurückgegeben.
$classname = get_class($this); while(false !== $classname) { // 'id' in EmployeeModel::$_fields['salary']? if(array_key_exists($name, $classname::$_fields)) { return $this->_values[$name] = $classname::$_fields[$name]->defaultValue; } $classname = get_parent_class($classname); }
Und wenn kein Feld für 'id'
gefunden wird, wird eine Exception geworfen.
$trace = debug_backtrace(); throw new Exception("Value $name does not exists in {$trace[0]['file']} on line {$trace[0]['line']}."); }// __get
__set()
funktioniert ähnlich, in dem nur dann $john->id = 42;
gesetzt wird, wenn in $john->_values[]
schon 'id'
vorhanden ist oder
ein Feld für 'id'
in der Klasse EmployeeModel
oder deren Elternklassen
gefunden wird.
public function __set($name, $value) { if(array_key_exists($name, $this->_values)) { $this->_values[$name] = $value; return; } $classname = get_class($this); while(false !== $classname) { if(array_key_exists($name, $classname::$_fields)) { $this->_values[$name] = $value; return; } $classname = get_parent_class($classname); } $trace = debug_backtrace(); throw new Exception("Value $name does not exists in {$trace[0]['file']} on line {$trace[0]['line']}."); }// __set
Das ist das grundlegende Funktionsprinzip von oop_fields_static.
Mal schauen, ob sich das nun für's RuBisCO-Framework benutzen lässt.