__get()例子来自Zandstra

时间:2011-04-27 22:55:57

标签: php get magic-methods

Matt Zandstra在他的文本“PHP Objects Patterns and Practice”中给出了以下示例来说明__get()方法:

class Person {
    function __get( $property ) {
        $method = "get{$property}";
        if ( method_exists( $this, $method ) ) {
            return $this->$method();
        }
    }
    function getName() {
        return "Bob";
    }
    function getAge() {
        return 44;
    }
}

实际上,我们知道我们永远不会实际创建这样的方法(getName和getAge)来返回这样的静态值,而是 - 我们将在对象中创建名称和年龄属性,并使用$ this运算符返回它们。 p>

我的问题是这个例子是否真的显示了效用。如果没有,有人可以提供一个更好的例子,说明为什么会出于同样的目的使用__get()?

提出要求的理由

如果我们在对象中使用name和age属性,那么无论如何都不会触发__get()函数,因为尝试使用以下函数获取这些属性:

$person = new Person();
$name = $person->name;

会导致name属性在公共时实际返回,如果是私有或受保护,则会导致可见性错误。 __get()函数不会在这些'真实'案例中执行......我错过了什么吗?

我完全清楚上面的代码是有效的。 我不相信这是一个实际的例子。

4 个答案:

答案 0 :(得分:1)

你是对的 - 我对你引用一本书感到印象深刻,这个例子很简单。

使用魔术__get方法调用方法是错误的,还有其他魔术方法只适用于这种用法:

  • __call()
  • __callStatic()
  • __invoke()
应使用

__get()__set()来读取和写入未声明的对象 属性

答案 1 :(得分:0)

正如php.net所述

  

“__ get()用于读取数据   来自无法进入的房产。“

这意味着每当您尝试访问不存在或属于私有/受保护的属性时,都会调用__get()(如果已定义)。上面的示例显示了一种方法,通过在有人试图获取值时调用其访问器(getter)来获取这些私有属性的值。

例如,调用

echo $a -> publicPropery or echo $a -> getPublicProperty()

会导致同样的事情。但是如果你打电话给$ a - > privateProperty你会得到一个错误,

$a -> getPrivateProperty() 

没关系。

但是,如果您在致电__get()时定义了$a -> privateProperty,则会执行__get()并重定向到$a -> getPrivateProperty()。在这种情况下,您总能成功获得价值并始终牢记安全。更重要的是,由于您在__get()中检查属性getter是否存在,如果有人试图访问不存在的属性,则会显示相应的错误或抛出异常,这将覆盖php的可见性错误。

答案 2 :(得分:0)

魔法方法的实际功能完全取决于开发人员以他们认为合适的任何方式处理。不同之处在于如何调用它们。

$obj->property; // invokes __get(), if defined
$obj->method(); // invokes __call(), if defined
$obj(); // invokes __invoke() if defined (php 5.3+)

等。因此,如果您希望__get()在内部调用方法,则可以。您希望如何处理它完全取决于您希望如何设计应用程序。

关于__get(),如果您有公开会员并尝试使用->进行调用,__get()将无法启动。但是,如果您尝试访问不可访问的成员(受保护,私有或不存在),__get()将会触发,您可以按照自己的喜好处理它。

据我了解,__get()至少根据php的主要目的是消除为每个成员编写getter的需要。与设置者的__set()比较。我不想在这里讨论这个问题,但我认为使用getter / setter会引起一些关于设计的危险信号。但是,除了开发应用程序的标准之外,不必遵守__get()的预期目的。

可能使用__get()的两个示例是初始化在实例化时可能不需要的属性(例如,通过DB查询),从而减少开销。另一个可能是如果你有属性存储在数组中,魔法get可能会返回映射到所请求属性的键的值。

使用php magic函数,你可以做一些非常酷的事情,你可以使用这些特殊的调用来编写更具可扩展性的代码。我喜欢做的事情:

class application {
   public function __call($_, $_) {
      throw new Exception("PUT and DELETE not supported");
   }
   public function POST() {
      //update data
      header("Location: $_SERVER[PHP_SELF]", true, 303);
   }
   public function GET() {
      //display data
   }
   public static function inst() {
      return new self;
   }
}

application::inst()->$_SERVER['REQUEST_METHOD']();

当然,这是使用__call()而不是__get(),但原则是相同的。在这种情况下,这只是一个完整性检查。

答案 3 :(得分:0)

    <?php
        class data {
            public $name="Ankur DalsaniYa"; \\ I wont to change name

            public function __get($var) {
                print "Attempted to retrieve '<b>$var</b>' and failed...\n";
                //$var is print the Unknown and Not Define but call variable print  
            }
        }

        $data = new data;
        echo "<br> Not Define Variable Call : ";
        print $data->title; // Not Defined variable Call then call __get function
        echo "<br><br> Define Variable Call : ";
        print $data->name;  // Define variable Call then Not call __get function
    ?>