PHP创造了 __set() 和 __get() 。你只需要写一个方法,就可以得到大部分的Getters和Setters。
class myTest{ public function __set($key,$value){ $this->$key = $value; } public function __get($key){ return $this->$key; }}$val = new myTest();$val->__set('m','我是m');echo $val->__get('m');
在转载的原文中,他在类里面定义了一个私有的变量,但是我测试的时候,不用定义变量也一样的可以输出,你通过魔术方法定义的变量的值,这个很奇怪。
有与在php的数组中,其长度是不限的,所以可以通过此方法给数组无限的添加元素
class myTest{ private $value = array(); public function __set($key,$value){ $this->value[$key] = $value; } public function __get($key){ return $this->value[$key]; }}$val = new myTest();$val->__set('c','我是m');echo $val->__get('c');
这样的话,如果是注册的页面,我们就可以灵活的获得和设置属性了。但是在实际运用中,我们知道传过来的值是不可靠的,我们得需要HTML转义,Mysql转义等等,所以我们可以写一个简单的回调函数,做数据验证的作用。
class myTest{ private $value = array(); private function validate($value){ return htmlspecialchars(addslashes($value)); } public function __set($key,$value){ $this->value[$key] = $this->validate($value); } public function __get($key){ return $this->value[$key]; } }$val = new myTest();$val->__set('c','我是......{><}a');echo $val->__get('c');
但是有的人不需要这样的,比如我前面提交的页面就有用户名和密码,不想再要别的了。当然,你如果用两个私有属性也可以解决,但是我说一下用一个数组的方法。
class myTest{ private $value = array('name'=>'Your name','password'=>'Your password'); private function validate($value){ return htmlspecialchars(addslashes($value)); } public function __set($key,$value){ if(isset($this->value[$key])){ $this->value[$key] = $this->validate($value); }else{ echo '不存在这样的属性'; } } public function __get($key){ if(isset($this->value[$key])){ return $this->value[$key]; }else{ echo '不存在这样的属性'; } } }$val = new myTest();$val->__set('name','我是......{><}a');echo $val->__get('name');
在PHP中关于 __isset() 和 __unset() 有个约定,就是当用 isset() 函数测试成员属性的时候,如果这个属性为public属性或者默认属性时,就不回调,当为protected或者private时就回调。
class Test{ var $a;//当这样设置变量的时候没有反映 //public $a;//这样设置变量也是没有反映 //private $a;//这样设置就有了反映 //protected $a;//这样设置有反映 public function __construct($value){ $this->a = $value; } public function __isset($name){ echo '你看到了我'; return isset($this->a);//返回真实的信息 } public function __unset($name){ echo '你不能看到我'; }}$test = new Test('我是一个参数');isset($test->a);
我测试的时候,只有将变量的属性设置为private和protected的时候起作用,但是当调用一个不存在的属性的时候,也会调用,或者这个类,里面根本就没有设置属性的实话,随便写一个也会调用,不晓得是为啥。
__unset()是一样的,这两个函数其实也有大作用,比如你做一个网游(我只是比喻,现实不是这样的),有个怪物类中有个属性是怪物的 血,你不能想unset()就unset(),也就是说你不能等怪物的血还有呢就使他死了。
class Monter{ /** * 怪兽的属性表 * * @var aray * */ private $state = array('hp'=>100,'mp'=>100); /** * 打击怪兽 * * @access public * @return void */ public function hit(){ $this->state['hp'] -= rand(1,10); } /** * 验证设定怪物的血是否合法 * * @param integer $value * @access private * @return void */ private function validate($value){ if(is_int($value) && $value){ return $value; }else{ return 0; } } /** * 设置怪兽属性 * * @param string $key * @param integer $value * @param public * @return void */ public function __set($key,$value){ if(isset($this->state[$key])){ $this->state[$key] = $this->validate($value); }else{ echo '没有这个属性!'; } } /** * 获取怪物的属性 * * @param string $key * @access public * @return integer */ public function __get($key){ if(isset($this->state[$key])){ return $this->state[$key]; }else{ echo '没有此属性'; } } /** * 查看是否存在怪物的状态 * * @param string $key * @return boolean */ public function __isset($key){ return isset($this->state[$key]); } /** * 查看怪物的属性是否为0 * * @param string $key * @access public * @return void * */ public function __unset($key){ if($this->state[$key] > 0){ echo '我还活着!那我就打'; }else{ unset($this->state[$key]); echo '我死了!太欺负人了,你胜利了!!!'; } }}$monter = new Monter();$monter->__set('hp',100);//设定怪物的血和蓝$monter->__set('mp', 100);//$monter->__set('血',200);//会输出错误while(isset($monter->hp)){//当怪物还存在的时候 echo '怪兽剩余的血量->'.$monter->__get('hp').'';//输出怪物剩余的血量,当怪物死后就输出没有次属性 echo '你还活着啊?'.$monter->hit();//开始打怪物 unset($monter->hp);//消灭怪物 }
呵呵呵,原来思路是这样的,:)