昨天晚上闲着无聊便弄起这玩意,感觉PHP5增加的类成员权限关键字挺好,但问题又来了,似乎还没一种方便的方式可以定义字段的getter以及setter,传统的方式是这样定义的:
classa
{
private$field;
publicfunctionget_field(){return$this->$field;}
publicfunctionset_field($value){$this->field=$value;}
}
虽然实现起来挺容易,但是说实在的,为一个字段去写这一堆代码还真不爽。。
于是便思索着是不是有一种更方便的方式来解决,并且可以方便地定义它的类型限制什么的。
捣鼓了半天(没办法,对它不熟。。),终于弄出一个类来解决这个问题:
classabstract_entity
{
private$fields;
private$sys_type=array(
"bool"=>"",
"array"=>"",
"double"=>"",
"float"=>"",
"int"=>"",
"integer"=>"",
"long"=>"",
"null"=>"",
"object"=>"",
"real"=>"",
"resource"=>"",
"string"=>""
//"mixed"and"number"
);
protectedfunction__construct($fields)
{
/*********************************
*$fields=array(
*"id"=array(
*"allow_null"=false,
*"value"=1,
*"type"="int"
*);
*);
**********************************/
$this->fields=$fields;
}
publicfunction__get($key)
{
if(array_key_exists($key,$this->fields))
{
return$this->fields[$key]["value"];
}
else
{
thrownewException("该属性不存在");
}
}
publicfunction__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',"returnis_$type($value);");
if(@$fun($value))
{
$this->fields[$key]["value"]=$value;
}
elseif($allow_null&&is_null($value))
{
$this->fields[$key]["value"]=NULL;
}
else
{
thrownewException("该值类型不正确,必须为".$type."类型");
}
}
elseif($type=="mixed")
{
if(!is_null($value))
{
$this->fields[$key]["value"]=$value;
}
elseif($allow_null)
{
$this->fields[$key]["value"]=NULL;
}
else
{
thrownewException("该值不允许为NULL值");
}
}
elseif($type=="number")
{
if(is_int($value)||is_float($value))
{
$this->fields[$key]["value"]=$value;
}
elseif(is_null($value)&&$allow_null)
{
$this->fields[$key]["value"]=NULL;
}
else
{
thrownewException("该值类型不正确,必须为".$type."类型");
}
}
else
{
if(class_exists($type)||interface_exists($type))
{
if(is_subclass_of($value,$type))
{
$this->fields[$key]["value"]=$value;
}
elseif(is_null($value)&&$allow_null)
{
$this->fields[$key]["value"]=NULL;
}
else
{
thrownewException("该值类型不正确,必须为".$type."类型");
}
}
elseif(is_null($value)&&$allow_null)
{
$this->fields[$key]["value"]=NULL;
}
}
}
else
{
thrownewException("该属性不存在");
}
}
}
通过定义一个一定格式的array可以比较方便地定义该字段的类型、是否允许NULL值以及默认值。
测试代码如下:
classtestextendsabstract_entity
{
publicfunction__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=newtest();
$a->id=123;
eche$a->id;
echo$a->ins1;
$a->ins1=NULL;
echois_null($a->ins1);
这里边实现了getter以及setter,但由于时间关系我没去实现readonly的功能,其实很简单,就是再加一项,标识它能不能被改写就成