在PHP中实现类似Java的getter和setter有很多方法。比较常用的有:直接箭头->call属性(最常用),不管这个属性有没有声明,都可以用,但是会报Notice级别的错误$dog=newDog();$dog->name='嘿';添加setter和getter方法,类似于JavaclassDog{private$name='';公共函数setName($name){$this->name=$name;}publicfunctiongetName(){return$this->name;}}使用魔法方法(maxx)classDog1{private$_name="";函数__set($property,$value){if($property==='name')$this->_name=$value;}function__get($property){if($property==='name')return$this->_name;}}以上三种方法,一般人都能想到前两种方法,对于第三种方法,PHP小白的第一印象是很强大(我想这人肯定是个大佬),但是这张照片真的能体现出来吗编程水平?对于这几种方法,我们来比较一下它们的执行效率:方法一代码:方法二代码:方法三代码:主要是两个for循环,外层循环10次,内层循环100万次。循环1000万次后,convert函数仅用于输出更易读的内存使用情况。现在本地测试一下,测试机是2015MBP,i516GB内存,PHP版本7.2.13(cli),执行结果如下:方法一:方法二:?方法三:方法三会是什么太慢了?可能有人会说,可能是因为魔术方法中的if判断,所以我现在尝试把if去掉:?执行结果如下:?我发现if的影响很小,这个不推荐写法。这里的magic方法是相当拦截器的,当调用未定义的属性时会调用magic方法,不过这只是测试,真实环境肯定不会这样写。从结果可以看出,直接使用箭头函数是最快的,最常用最简单的方法执行效率最高。后两种方式不仅代码行数多,执行效率也比第一种低,尤其是使用了魔法方法,执行效率是第一种的6倍左右,是第一种的2倍左右第二种。古人常说“智者思多必失,愚者思多必获益”。大概就是这个意思吧。这里的代码行数和执行效率都增加了。但是,对于第一种方法,可读性不是很高。无论属性是否定义,都可以随意调用。代码不规范。别人查看你的代码不是很方便。建议在使用之前声明该属性。向下。还有什么妙法?在PHP中,__call()方法可能是最有用的魔术方法,用它可以实现棘手的事情。当要调用类中未定义的方法时,将调用__call()。第一个参数是要调用的未定义方法的名称,第二个参数是传递给调用方法的所有参数的数组。__call()的返回值会返回给调用者,就像调用一个真正的方法一样。同时,__call也可以用来实现委托。委托意味着一个对象将请求转发给另一个对象,并将请求的处理委托给另一个对象。这有点类似于继承,也有点类似于在子类中调用父类的方法。但是在继承中,父类和子类的关系是固定的,使用委托可以在运行时改变所使用的对象。委托比继承具有更大的灵活性。代码如下:代码中,Doctor类接收一个PersonWriter对象作为构造函数的参数,存入$printer中,在__call()中检查PersonWriter中是否有$methodName方法,如果存在,委托PersonWriter对象来处理,并将当前类Doctor的实例传给它,运行结果如下:这样我们就不需要在Doctor中手动调用如下方法:$this->打印机->printMe($this);如果你在PersonWriter中添加几个新的使用委托可以节省很多时间,但代码也会变得不清楚和难以理解。对于调用者来说,你提供的是动态接口,没有办法反射(reflection),因为调用类和委托类的交互比较模糊,使用时需要提供文档。回到文章的主题,我们比较了PHP中getter和setter的使用。从一个Java程序员的角度来看,第二种方法中规中矩,没有什么套路。第一种和第三种方法应该是PHP特有的,但是第三种方法的执行效率远低于前两种。虽然第一种方式效率最高,但最好在使用时声明属性,使代码结构更清晰。
