PropertyObject类帮助

时间:2010-08-08 18:25:01

标签: php

我是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;

     }
}

}
?>

我无法理解评估者内部的代码获取和设置方法。

2 个答案:

答案 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”一词定义的函数。因此,假设foopropertyTable中的关键,__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数组。