代码之家  ›  专栏  ›  技术社区  ›  Jose Vega

PHP魔术方法集和get

php
  •  3
  • Jose Vega  · 技术社区  · 14 年前

    这样做会被认为是好的做法吗。。。

    我有以下定义的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方法,我使用了magic方法来为我需要的属性调用受人尊敬的getter,或者只返回属性的值而不做任何更改。这可以看作是一种好的做法吗?

    4 回复  |  直到 14 年前
        1
  •  7
  •   user187291    14 年前

    不知道最佳实践,但当需要延迟加载属性时(例如,当获取涉及复杂钙化或数据库查询时),g e t会非常有用。此外,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!
    
        2
  •  3
  •   webbiedave    14 年前

    这可以被认为是好的做法吗?

    这取决于你试图解决的问题,但一般来说,我不是来自于思想学派,魔术方法只应该用来解决现有的问题,而这些问题是不能用其他实用的方法解决的,而不是把它们作为设计的基础。

    你所做的很多事情都可以用真正的getter/setter来处理。PHP没有真正的属性,因此将它们强加于您的类肯定是不可取的。

        3
  •  2
  •   pilsetnieks    14 年前

    你来自爪哇,是吗?

    不管怎样,如果你只是不加选择地获取和设置这些财产,就把它们公之于众。如果需要对数据执行其他操作(除了分配给变量和读取变量之外),请使用get、set和private属性。

        4
  •  1
  •   Community CDub    8 年前

    不,这不是因为这些神奇的方法是拦截器,可以在PHP抛出错误之前处理对不可访问属性的任何调用。他们不能代替适当的接球手和二传手。

    They also behave differently as stated in the Manual:

    $a=$obj->b=8;

    他们也是 slower to execute with a significant performance impact . 你的API也会变得不那么透明,因为所有神奇的事情都会让人费解。