博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php---魔术函数(__set()和__get()和isset()和unset())
阅读量:6253 次
发布时间:2019-06-22

本文共 4570 字,大约阅读时间需要 15 分钟。

hot3.png

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);//消灭怪物 }

呵呵呵,原来思路是这样的,:)

转载于:https://my.oschina.net/zhangdapeng89/blog/40276

你可能感兴趣的文章
IDEA中使用Maven创建Java Web项目
查看>>
2017.12.25
查看>>
react--1.创建项目
查看>>
11月20日学习内容整理:jquery插件
查看>>
预科班第四次考核总结
查看>>
html
查看>>
数据分析师到底在做什么?
查看>>
pt-heartbeat工具监控MySQL复制延迟
查看>>
指尖下的js —— 多触式web前端开发之三:处理复杂手势(转)
查看>>
spring boot项目配置文件集合
查看>>
cube-ui的用法
查看>>
2015.4.21 SetWindowPos函数用法
查看>>
2011-12-14 调用cmd并获得输入输出+网络访问
查看>>
TCP定时器详解
查看>>
if判断,switch语句
查看>>
Arduino入门之前
查看>>
zoj 1904 Beavergnaw 计算圆柱和圆台的体积
查看>>
整理了一份招PHP高级工程师的面试题(转)
查看>>
学习Raft算法的笔记
查看>>
第十一周编程总结
查看>>