其实__isset() 和 __unset() 与 __sleep()和__wakeup() 是有点像的,__isset() 和 __unset() 是在触发isset()和unset()函数前的回调函数。我们继续来做例子。
[php]
class Test {
public $a;
public function __construct($value) {
$this->a = $value;
}
public function __isset($name) {
echo "你小子偷看我??";
}
public function __unset($name) {
echo "你没权利宰了我!";
}
}
$test = new Test("我是a");
isset($test->a); //无任何输出
[/php]
执行上面的代码,结果无任何输出,但是刚才我说了,只要执行isset()就要执行__isset()这个回调函数的啊,回调函数里面输出 “你小子偷看我??” ,但是为什么结果却没有输出呢?难道是我说错了??我不能欺骗大家啊,所以我得给大家说清楚,不是我错了,也不是程序错了,是PHP的问题!
在PHP中关于 __isset() 和 __unset() 有个约定,就是当用 isset() 函数测试成员属性的时候,如果这个属性为public属性或者默认属性时,就不回调,当为protected或者private时就回调。我语言表达能力 差,还是用代码表示吧。
[php]
class Test {
var $a; //这样就不输出
public $a; //这样也不输出
protected $a; //输出 你小子偷看我??
private $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("我是a");
isset($test->a);
[/php]
这样明白了吧?__unset()是一样的,这两个函数其实也有大作用,比如你做一个网游(我只是比喻,现实不是这样的),有个怪物类中有个属性是怪物的 血,你不能想unset()就unset(),也就是说你不能等怪物的血没完了就使他死了。我还用例子说明。这个例子我自认为相当的好,自恋一下:)把上 面的内容都囊括了,希望你可以好好执行下,分析下,为什么会出这样的结果。
[php]
class Monster {
/**
* 怪物的属性表
*
* @var array
*/
private $state = array('hp' => 100, 'mp' => 100);
/**
* 打击怪物
*
* @access public
* @return void
*
*/
public function hit() {
$this->state['hp'] = $this->state['hp'] - rand(1, 10);
}
/**
* 设置怪物属性
*
* @param string $key
* @param integer $value
* @access 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 integer $value
* @access private
* @return void
*/
private function validate($value){
if (is_int($value) && $value > 0) {
return $value;
} else {
return 0;
}
}
/**
* 查看是否存在怪物的状态
*
* @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 '我死了!';
}
}
}
$monster = new Monster();
$monster->__set('hp', 100); //设定怪物的血和蓝
$monster->__set('mp', 100);
$monster->__set('血', 200); //输出 没有此属性!
while (isset($monster->hp)) { //当怪物还存在的时候
$monster->hit(); //开始打怪
unset($monster->hp); //消灭怪物
echo $monster->__get('hp'); //输出怪物剩余血量 当怪物死后输出 没有此属性!
}
[/php]
写网游一直是儿时的梦想,但是现在比较现实了,根本不可能,所以我就在这里写个虚假的类来YY下吧,大家不要BS我:)
好了,今天的笔记到此为止,明天我们将要学习 __call() 。构造函数和析构函数我不准备说了,思想不是PHP里特有的,看些OOP的教程都有讲。
明天要毕业答辩,不知道笔记会不会按时发布,请期待。
(责任编辑:ken)