我是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;
}
}
}
?>
我无法理解评估者内部的代码获取和设置方法。
答案 0 :(得分:1)
当请求对象的属性但未声明或特别指定(对于动态属性)时,将调用__get
魔术方法。这个实现:
$propertyTable
的实际声明属性中的条目存在。'get'.$propertyName
的方法(即,"get"
与请求属性名称连接),则调用该方法并返回其值。$propertyName
中返回带有键$propertyTable
的条目的值。鉴于此,我认为你可以想出__set
。请参阅PHP手册中的Magic Methods。
答案 1 :(得分:1)
这是设置数据库存储类的一种非常常见的方法。会发生什么是基于PropertyObject实例化对象(因为PropertyObject是抽象的)
class MyObj extends PropertyObject {
}
$m = new MyObj();
继承了__get()
和__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
最后,如果foo
中有一个键propertyTable
但没有名为getfoo
的方法,则只会返回$m->data
中数组位置的值是propertyTable
中数组位置的值,其键为foo
__set()
的定义方式大致相同,但不是返回存储在data
数组中的值,而是检查前置'set',并检查是否在object与data
数组中的值有任何不同,如果是,则在设置新值之前将属性名称添加到changedProperties数组。