Я написал родительский класс (с использованием поздней статической привязки), от которого унаследованы классы моей базы данных. Я пытаюсь написать конструктор, чтобы назначить каждый столбец таблицы как открытое свойство дочерних классов. До сих пор я мог написать конструктор в дочерних классах, который прекрасно работает, но я хочу поместить его в родительский класс, чтобы все свойства дочерних классов определялись автоматически.
Вот мой детский класс:
class Sale extends DatabaseObject {
protected static $table_name="invoices";
protected static $db_fields = array();
function __construct() {
global $database;
$query_cols = " SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME LIKE '" . self::$table_name . "' AND TABLE_SCHEMA LIKE '" . DB_NAME . "' ORDER BY ORDINAL_POSITION ASC";
$cols = $database->query($query_cols);
while($col = $database->fetch_array($cols)) {
if(!property_exists($this,$col['COLUMN_NAME'])) {
$this->$col['COLUMN_NAME']=NULL;
array_push(self::$db_fields,$col['COLUMN_NAME']);
}
}
}
}
Чтобы использовать этот конструктор в родительском объекте, мне нужно определить свойство вызываемого класса.
function __construct() {
$class_name = get_called_class();
$query_cols = " SELECT COLUMN_NAME FROM information_schema WHERE TABLE_NAME LIKE '" . static::$table_name . "' AND TABLE_SCHEMA LIKE '" . DB_NAME . "'";
$query_cols .= " ORDER BY ORDINAL_POSITION ASC";
$cols = $database->query($query_cols);
while($col = $database->fetch_array($cols)) {
if(!property_exists($class_name,$col['COLUMN_NAME'])) {
// the code to define called class public property?!
}
}
}
Заранее спасибо.
Как правило, если вы обращаетесь к статическим членам класса, вы можете использовать static :: $ foo, а не self :: $ foo, однако вам нужно будет повторно объявить пустую начальную статическую переменную для каждого дочернего класса, иначе он будет использовать статический член родителя.
Альтернативный подход, который я использую для системы Model, заключается в использовании имени класса как части структуры массива.
Так что вместо
array_push(self::$db_fields,$col['COLUMN_NAME']);
ты бы сделал
array_push(self::$db_fields[$class_name],$col['COLUMN_NAME']);
Таким образом, вы в основном имеете один массив на уровне родительского класса, причем каждый элемент представляет собой массив полей дочернего класса, который определяется их именем класса.
Других решений пока нет …