教学之友,学习之友。

站长教学网

当前位置: 站长教学网 > 网站编程 > PHP教程 >

PHP类中的魔术方法使用实例讲解(2)

时间:2012-08-03 16:09来源:未知 作者:ken 点击:

其实__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)

TAG标签: php 魔术方法
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
注册登录:不允许匿名留言,登录后留言无需输入验证码。
栏目列表
最新内容