【问题标题】:php the point for __get() and __set() magicphp __get() 和 __set() 魔法的要点
【发布时间】:2010-12-09 06:29:48
【问题描述】:

PHP 5 引入了魔术方法 __get() 和 __set()。据我了解,这是编写每个成员的 getter 和 setter 的捷径;

 <?php
class Person {
    private $firstname;
    private $lastname;

    function __set($var, $name) {
        $this->$var = $name;
    }

    function __get($var) {
        return $this->$var;
    }
}

$person = new Person();
$person->firstname = "Tom";
$person->lastname = "Brady";


echo $person->firstname . " " . $person->lastname;

// print: Tom Brady
?>

我的问题是,这就像公开成员变量一样。

class Person {
    public $firstname;
    public $lastname;
}

这不违反 OOP 原则吗?还有什么意义?

【问题讨论】:

标签: php oop


【解决方案1】:

需要理解的是,“OOP 原则”并不是一成不变的。 它们更像是经验法则。

因此,例如在 python 中,所有成员变量都是公共的。没有真正的私有变量。

在 Smalltalk 中,所有变量都是私有的,如果您想提供对需要 getter 的变量的访问,则没有公共变量。事实上,这里是 getter 和 setter 实践的起源。

所以 php 中的神奇 getter 和 setter 在很多情况下都可以派上用场。 例如:

  • ORMappers
  • 当您构建要发送到外部 API 的对象时
  • 当您想识别访问变量的人时。

现在,如果您想保留私有变量并仍然使用魔法 getter 和 setter 再次针对您的应用程序的特定情况,您可以修改您的代码 对私有变量使用“_”下划线约定。

<?php
class Person {
    private $_firstname;
    private $_lastname;

    function __set($name, $value) {
        if (!strpos('_', $name) === 0) {
            $this->$name = $value;
        } else {
            throw new Exception ("trying to assign a private variable");
        }
    }

    function __get($name) {
        if (!strpos('_', $name) === 0) {
            retrun $this->$name;
        } else {
            throw new Exception ("trying to read a private variable");
        }
    }
}

?>

【讨论】:

    【解决方案2】:

    在您的示例中,这与将它们公开是一样的。但是,您的 __set 和 __get 函数不必处理所有变量。 (也许使用 switch 语句来决定您要处理哪个。)此外,您可以对 __set 的参数执行数据验证,或者为根本不存在的 __get 计算返回值。

    刚刚注意到您在代码中使用 $this->var 而不是 $this->$var (我认为您希望代码正常工作)

    【讨论】:

      【解决方案3】:

      首先,您的示例不应该工作,因为您正在访问$this-&gt;var

      第二:是的,添加魔法 setter 和 getter 就像添加 setter 和 getter。只是魔法。

      __set 和 __get 有一些用途:如果您正在构建一个库,例如 ORM,它可能会派上用场。此外,它还可以用作穷人的属性:如果您最初公开了一个字段,您现在可以在 __set 和 __get 中添加行为,就好像它一直都在一样(例如验证)。

      【讨论】:

      • thx.. 我将代码更改为 $this->$var。这可能很难调试代码。
      猜你喜欢
      • 2011-06-10
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      相关资源
      最近更新 更多