Я новичок в 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, прежде чем устанавливать новое значение.