Это - то, что я имею: Все объекты, которые могут быть сохранены на базе данных, расширяют абстрактный класс DatabaseObject, который имеет весь логический код, чтобы на самом деле наблюдать за изменениями атрибута и выполнить запросы databas.
Я использую две статических переменные для определения определенных для объекта деталей. Я определяю их в общем в базовом классе, и затем предположительно, я перезаписываю их в фактических объектах базы данных.
Проблема: Когда код в родительском классе на самом деле выполнен, он использует старое родительское значение вместо текущего объектного значения.
Вот код для базового класса:
abstract class DatabaseObject {
public $id;
private static $databaseTable = NULL;
private static $databaseFields = array();
private $data = array();
private $changedFields = array();
public function IDatabaseObject($id) {
$this->id = $id;
$this->data = Database::GetSingle(self::$databaseTable, $id);
Utils::copyToObject($this, $this->data, self::$databaseFields);
}
public static function Load($id) {
return new self($userID);
}
public static function Create($data) {
$id = Database::Insert(self::$databaseTable, $data);
return new self($id);
}
public function Save() {
$data = Utils::copyFromObject($this, $this->changedFields);
Database::Update(self::$databaseTable, $data, $this->id);
}
public function __constructor() {
// We do this to allow __get and __set to be called on public vars
foreach(self::$databaseFields as $field) {
unset($this->$field);
}
}
public function __get($variableName) {
return $this->$variableName;
}
public function __set($variableName, $variableValue) {
// We only want to update what has been changed
if(!in_array($variableName, $this->changedFields) && in_array($variableName, self::$databaseFields)) {
array_push($this->changedFields, $variableName);
}
$this->$variableName = $variableValue;
}
}
И вот код для одного из объектов, расширяющих базовый класс выше:
class Client extends DatabaseObject {
public static $databaseTable = "clients";
public static $databaseFields = array("name","contactName","primaryUserID","email","is_active","rg","cpf","cnpj","ie","addrType","addrName","addrNumber","addrComplement","addrPostalCode","addrNeighborhood","addrCity","addrState","addrCountry","phoneLandline","phoneFax","phoneMobile");
public $name;
public $contactName;
public $primaryUserID;
public $email;
public $is_active;
public $rg;
public $cpf;
public $cnpj;
public $ie;
public $addrType;
public $addrName;
public $addrNumber;
public $addrComplement;
public $addrPostalCode;
public $addrNeighborhood;
public $addrCity;
public $addrState;
public $addrCountry;
public $phoneLandline;
public $phoneFax;
public $phoneMobile;
public static function Load($id) {
return new Client($id);
}
}
Что я делаю неправильно здесь? Есть ли иначе, я могу достигнуть того же результата?
Краткое приложение: Я объявляю, что атрибуты в теле класса главным образом позволяют ему быть замеченным функцией автоматического заполнения NetBeans.
Вы ищете Позднюю статическую привязку .
Таким образом, вам нужно использовать:
static::$databaseTable
вместо
self::$databaseTable
Эта функция доступна, начиная с PHP 5.3. Имитировать это в PHP 5.2 очень сложно по двум причинам: get_called_class
также доступен только с PHP 5.3. Следовательно, это также необходимо моделировать, используя debug_backtrace
. Вторая проблема заключается в том, что если у вас есть вызываемый класс, вы все равно не можете использовать $ calledClass :: $ property
, потому что это тоже функция PHP 5.3. Здесь вам нужно использовать eval
или Reflection
. Так что я очень надеюсь, что у вас PHP 5.3;)