最佳实践__get()和__set()[闭](Best Practices for __get()

2019-09-20 19:18发布

出于此问题上使用__get()__set()来访问私有变量,我想获得它们是如何在一般使用的输入。 我不知道何时何地会使用重载函数的最佳时机,并在您使用一个(如果有)。

只是要清楚,我们正在谈论这些功能: http://us2.php.net/manual/en/language.oop5.magic.php

Answer 1:

懒惰模型吸气剂(使用__get())

我不记得使用PHP的魔术方法常常在我的应用程序,但我记得一个情况__get()是非常有用的。

早在天我正在开发中的CakePHP框架的应用程序,它有很多的模型,即使方法只利用一个或两个人(这蛋糕是如何工作的),它们在特定的控制器使用的所有模型初始化。 所以我决定改变这种懒模型懒(加载模型时,它们被用于第一次)。

我所做的一切是我添加了一个非常简单的__get()看起来有特定名称的型号和装载了它的功能。 这就像3-4行代码。 我定义在AppController的(所有的CakePHP类从控制器派生),突然我的应用程序获得的速度和使用较低的内存。

我把它再后来,也懒言成分以相同的方式加载。

动态模型方法(使用__call())

另一个很好的例子,也从CakePHP的,是蛋糕上的模型如何搜索。 基本上,你必须为两种方法: find()findAll()在每一个模型,但你也可以搜索使用方法findBy<FieldName>()findAllBy<FieldName>()

在举例来说,如果你有db表

notes(id, date, title, body)

并创建该蛋糕模型。 您可以使用诸如findById() findByTitle()等。 你只需要首字母大写的数据库字段,你可以做任何领域的搜索快得多。

蛋糕用做它__call()魔术方法。 如果您正试图执行不存在法这种方法被调用,那么它只是运行find()findAll()与方法的名称和参数动态创造了条件。 这是贯彻落实,可以给你真的有很多好处很简单。



Answer 2:

我用__get()和__set()来访问的私人阵列,即元素:

class Something {
    private $data;

    public function __set($key, $value) {
        //put validation here
        $this->data[$key] = $value;
    }

    public function __get($key) {
        if (!array_key_exists($this->data, $key)) {
             throw new Exception("Invalid member $key.");
        } else {
             return $this->data[$key];
        }
    }
}

因此,与一些验证,像$人 - >年龄=“ASDF”马上会抛出异常(而这将是罚款,如果年龄是一个公共成员。)

另外,在__set(),您可以限制哪些键是有效的,如果你不想在你的班上任意“成员”。



Answer 3:

一些示例:

class formatedContainer {
    private $holder;
    protected $mode = "formated";

    public function __set($var, $value) {
        $formated = chunk_split($value, 4, "-");
        if(substr($formated, -1) == "-") 
            $formated = substr($formated, 0, strlen($formated) - 1);
        $this->holder[$var] = array('formated' => $formated, 'plain' => $value);
    }

    public function __get($var) {
        return $this->holder[$var][$this->mode];
    }

    public function getPlain() {
        $this->mode = "plain";
    }

    public function getFormated() {
        $this->mode = "formated";
    }
}

$texts = new formatedContainer();
$texts->myText = md5(uniqid());
$texts->anotherText = md5("I don't change!");

//Prints something like: 440e-6816-b2f5-7aa5-9627-9cc8-26ef-ef3b
echo $texts->myText;

$texts->getPlain();

//Prints something like: 8559d37c5a02714dca8bd1ec50a4603a
echo "<br/>" . $texts->anotherText;

有点窝囊,但我认为你可以得到一个想法。 :}



Answer 4:

有很多在网络上的例子,使用__get()__set()与私有“属性数组”相结合。 有趣的扭曲我在类定义想要的,是能够实际声明的公共属性和仍然使用这些神奇的拦截器 - 更多的自我记录代码,并给我的IDE做的代码完成,等通常的能力,如果这些属性声明, __get()__set()将不会被调用。 我发现,如果我unset()那些相同的属性在我的类的构造函数,我能得到两全其美。



文章来源: Best Practices for __get() and __set() [closed]