实现了一个PHP5的getter/setter基类的代码

  PHP3、PHP4都拥有类,但它们的类定义的实在很不像样,效率还挺难为情的,但资料上说PHP5重新构造了面向对象的支持,尽管并不是完全面向对象,但也算能拿出来见人了。

  昨天晚上闲着无聊便弄起这玩意,感觉PHP5增加的类成员权限关键字挺好,但问题又来了,似乎还没一种方便的方式可以定义字段的getter以及setter,传统的方式是这样定义的:

  class a

  {

  private $field;

  public function get_field() { return $this->$field; }

  public function set_field($value) { $this->field = $value; }

  }

  虽然实现起来挺容易,但是说实在的,为一个字段去写这一堆代码还真不爽。。

  于是便思索着是不是有一种更方便的方式来解决,并且可以方便地定义它的类型限制什么的。

  捣鼓了半天(没办法,对它不熟。。),终于弄出一个类来解决这个问题:

  class abstract_entity

  {

  private $fields;

  private $sys_type = array(

  "bool" => "",

  "array" => "",

  "double" => "",

  "float" => "",

  "int" => "",

  "integer" => "",

  "long " => "",

  "null" => "",

  "object" => "",

  "real" => "",

  "resource" => "",

  "string" => ""

  // "mixed" and "number"

  );

  protected function __construct($fields)

  {

  /*********************************\

  * $fields = array(

  *     "id" = array(

  *        "allow_null" = false,

  *        "value" = 1,

  *        "type" = "int"

  *     );

  * );

  \**********************************/

  $this->fields = $fields;

  }

  public function __get($key)

  {

  if(array_key_exists($key, $this->fields))

  {

  return $this->fields[$key]["value"];

  }

  else

  {

  throw new Exception("该属性不存在");

  }

  }

  public function __set($key, $value)

  {

  if(array_key_exists($key, $this->fields))

  {

  $allow_null = $this->fields[$key]["allow_null"];

  $type = $this->fields[$key]["type"];

  if(array_key_exists($type, $this->sys_type))

  {

  $fun = create_function('$value', "return is_$type($value);");

  if(@$fun($value))

  {

  $this->fields[$key]["value"] = $value;

  }

  else if($allow_null && is_null($value))

  {

  $this->fields[$key]["value"] = NULL;

  }

  else

  {

  throw new Exception("该值类型不正确,必须为" . $type . "类型");

  }

  }

  else if($type == "mixed")

  {

  if(!is_null($value))

  {

  $this->fields[$key]["value"] = $value;

  }

  else if($allow_null)

  {

  $this->fields[$key]["value"] = NULL;

  }

  else

  {

  throw new Exception("该值不允许为NULL值");

  }

  }

  else if($type == "number")

  {

  if(is_int($value) || is_float($value))

  {

  $this->fields[$key]["value"] = $value;

  }

  else if(is_null($value) && $allow_null)

  {

  $this->fields[$key]["value"] = NULL;

  }

  else

  {

  throw new Exception("该值类型不正确,必须为" . $type . "类型");

  }

  }

  else

  {

  if(class_exists($type) || interface_exists($type))

  {

  if(is_subclass_of($value, $type))

  {

  $this->fields[$key]["value"] = $value;

  }

  else if(is_null($value) && $allow_null)

  {

  $this->fields[$key]["value"] = NULL;

  }

  else

  {

  throw new Exception("该值类型不正确,必须为" . $type . "类型");

  }

  }

  else if(is_null($value) && $allow_null)

  {

  $this->fields[$key]["value"] = NULL;

  }

  }

  }

  else

  {

  throw new Exception("该属性不存在");

  }

  }

  }

  通过定义一个一定格式的array可以比较方便地定义该字段的类型、是否允许NULL值以及默认值。

  测试代码如下:

  class test extends abstract_entity

  {

  public function __construct()

  {

  $define = array(

  "id" => array(

  "allow_null" => false,

  "value" => 1,

  "type" => "int"

  ),

  "name" => array(

  "allow_null" => false,

  "value" => "abc",

  "type" => "string"

  ),

  "gender" => array(

  "allow_null" => false,

  "value" => true,

  "type" => "bool"

  ),

  "ins" => array(

  "allow_null" => false,

  "value" => $this,

  "type" => "test"

  ),

  "ins1" => array(

  "allow_null" => true,

  "value" => $this,

  "type" => "test"

  ),

  "ins2" => array(

  "allow_null" => true,

  "value" => NULL,

  "type" => "config_media_type"

  )

  );

  parent::__construct($define);

  }

  }

  $a = new test();

  $a->id = 123;

  eche $a->id;

  echo $a->ins1;

  $a->ins1 = NULL;

  echo is_null($a->ins1);

  这里边实现了getter以及setter,但由于时间关系我没去实现readonly的功能,其实很简单,就是再加一项,标识它能不能被改写就成