Я новичок в php, и в настоящее время я читаю Wrox Professional PHP 5.
Может ли кто-нибудь объяснить мне следующий код?
<? php abstract class PropertyObject { //Stores name/value pairs that hook properties to database field names protected $propertyTable=array(); //List of properties that have been modified. protected $changedProperties=array(); //Actual data from the database. protected $data; //Any validation errors that might have occured. protected $errors=array(); public function __construct($arData) { $this->data=$arData; } function __get($propertyName) { if(!array_key_exits($propertyName,$this->propertyTable)) { throw new Exception("Invalid property \"$propertyName\" !"); } if(method_exists($this,'get'.$propertyName)) { return call_user_func(array($this,'get'.$propertyName)); } else { return $this->data[$this->propertyTable[$propertyName]]; } } function __set($propertyName,$value) { if(!array_key_exits($propertyName,$this->propertyTable)) { throw new Exception("Invalid property \"$propertyName\" !") } if(method_exits($this,'set'.$propertyName)) { return call_user_func(array($this,'set'.$propertyName),$value); } else { //If the value of the property really has changed and it's not already in the changedProperties array, add it. if($this->propertyTable[$propertyName] !=$value && !in_array($propertyName,$this->changedProperties)) { $this->changedProperties[]=$propertyName; } //Now set the new value $this->data[$this->propertyTable[$propertyName]]=$value; } } } ?>
Я не могу понять код внутри метода получения и установки методов.
Магический метод __get вызывается, когда запрашивается свойство объекта, но оно не было объявлено или специально не назначено (для динамических свойств). Эта реализация:
$propertyTable . 'get'.$propertyName (т.е. "get" с именем свойства запроса), этот метод вызывается и возвращается его значение. $propertyName в объявленном свойстве $propertyTable . Учитывая это, я думаю, вы можете вычислить __set out. См. « Магические методы» в руководстве по PHP.
Это очень распространенный способ настройки класса хранения БД. Что происходит, вы создаете экземпляр объекта на основе PropertyObject (поскольку PropertyObject является абстрактным)
class MyObj extends PropertyObject { } $m = new MyObj();
__set() методы __get() и __set() . Каждый раз, когда доступ к данным объекта осуществляется через оператор -> , __set() методы __get() и __set() .
$m->foo; #calls MyObject::__get('foo'); $m->bar = 'baz'; #calls MyObject::__set('bar','baz');
Метод __get() сначала проверяет, существует ли ключ, определенный в таблице свойств (который здесь моделирует поля из БД), а если он не существует, генерирует исключение. Затем get() увидит, есть ли функция, определенная с добавлением слова get. Таким образом, предполагая, что foo является ключом в propertyTable , __get() увидит, был ли мы определен метод getfoo , и если бы у нас это было, назовите его для нас и верните его значение.
//if(method_exists($this,'get'.$propertyName)) //{ // return call_user_func(array($this,'get'.$propertyName)); //} $m->foo; # checks if MyObj::getfoo is defined, and if so, calls it
Наконец, если в propertyTable есть ключ foo но нет метода с именем getfoo , он просто возвращает значение позиции массива в $m->data чей ключ является значением позиции массива в propertyTable чей ключ является foo
__set() определяется точно так же, но вместо того, чтобы возвращать значение, хранящееся в массиве data вместо этого проверяет заранее заданный «набор» и проверяет, не зависит ли значение, заданное на объекте, от значения в массив data , и если это так, добавляет имя свойства в массив changedProperties, прежде чем устанавливать новое значение.