繁体   English   中英

PHP Magic Methods __set和__get

[英]PHP Magic Methods __set and __get

这样做会被认为是好的做法......

我有A类,其定义如下:

 class A{
      private $_varOne;
      private $_varTwo;
      private $_varThree;
      public $varOne;


      public function __get($name){

   $fn_name = 'get' . $name;

         if (method_exists($this, $fn_name)){
             return $this->$fn_name();
   }else if(property_exists('DB', $name)){
             return $this->$name;
   }else{
    return null;
   }
      }

  public function __set($name, $value){

   $fn_name = 'set' . $name;

   if(method_exists($this, $fn_name)){
    $this->$fn_name($value);
   }else if(property_exists($this->__get("Classname"), $name)){
    $this->$name = $value;
   }else{
    return null;
   }

  }

      public function get_varOne(){
           return $this->_varOne . "+";
      }


 }

 $A = new A();
 $A->_varOne;     //For some reason I need _varOne to be returned appended with a +

 $A->_varTwo;     //I just need the value of _varTwo

为了不创建4个set和4个get方法,我使用了魔术方法来为我需要的属性调用受尊重的getter,或者只是返回属性的值而不做任何改变。这可以考虑这个好习惯吗?

不了解最佳实践,但是当需要延迟加载属性时__get非常有用,例如,当获取它涉及复杂的钙化或数据库查询时。 此外,php提供了一种优雅的方法来缓存响应,只需创建一个具有相同名称的对象字段,这样可以防止再次调用getter。

class LazyLoader
{
    public $pub = 123;

    function __get($p) {
        $fn = "get_$p";
        return method_exists($this, $fn) ? 
            $this->$fn() : 
            $this->$p; // simulate an error
    }

    // this will be called every time  
    function get_rand() {
        return rand();
    }

    // this will be called once
    function get_cached() {
        return $this->cached = rand();
    }
}

$a = new LazyLoader;
var_dump($a->pub);       // getter not called
var_dump($a->rand);      // getter called 
var_dump($a->rand);      // once again 
var_dump($a->cached);    // getter called 
var_dump($a->cached);    // getter NOT called, response cached
var_dump($a->notreally); // error!

这可以算是好的做法吗?

取决于你想要解决的问题,但总的来说,没有。 我来自思想学派,魔术方法应该只用于解决任何其他实际方法无法解决的现有问题,而不是用它们作为设计的基础。

你所做的很多事情都可以通过真正的getter / setter来处理。 PHP没有真正的属性,所以强迫它们上课是绝对不利的。

你来自Java,不是吗?

无论如何,如果你只是不加选择地设置这些属性,只需将它们公之于众。 如果除了分配和读取变量之外,还需要对数据执行其他操作,请使用__get,__ set和私有属性。

此外,您可能会看到通常会说魔术方法会妨碍性能等等,但这应该只是在高使用率情况下才会引起关注 - 通常瓶颈是磁盘I / O,数据库或某些情况下内存/ CPU密集型操作

不,这不是因为这些魔术方法是拦截器,可以在PHP抛出错误之前处理对不可访问属性的任何调用。 它们不能替代正确的吸气剂和制定者。

它们的行为也与手册中所述的不同:

由于PHP处理赋值运算符的方式,忽略__set()的返回值。 类似地,在将赋值链接在一起时,永远不会调用__get():$ a = $ obj-> b = 8;

它们的执行速度较慢,会对性能产生重大影响 你的API也会变得不那么透明,因为所有神奇地做某事的东西都令人费解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM