出于此问题上使用__get()
和__set()
来访问私有变量,我想获得它们是如何在一般使用的输入。 我不知道何时何地会使用重载函数的最佳时机,并在您使用一个(如果有)。
只是要清楚,我们正在谈论这些功能: http://us2.php.net/manual/en/language.oop5.magic.php
出于此问题上使用__get()
和__set()
来访问私有变量,我想获得它们是如何在一般使用的输入。 我不知道何时何地会使用重载函数的最佳时机,并在您使用一个(如果有)。
只是要清楚,我们正在谈论这些功能: http://us2.php.net/manual/en/language.oop5.magic.php
我不记得使用PHP的魔术方法常常在我的应用程序,但我记得一个情况__get()
是非常有用的。
早在天我正在开发中的CakePHP框架的应用程序,它有很多的模型,即使方法只利用一个或两个人(这蛋糕是如何工作的),它们在特定的控制器使用的所有模型初始化。 所以我决定改变这种懒模型懒(加载模型时,它们被用于第一次)。
我所做的一切是我添加了一个非常简单的__get()
看起来有特定名称的型号和装载了它的功能。 这就像3-4行代码。 我定义在AppController的(所有的CakePHP类从控制器派生),突然我的应用程序获得的速度和使用较低的内存。
我把它再后来,也懒言成分以相同的方式加载。
另一个很好的例子,也从CakePHP的,是蛋糕上的模型如何搜索。 基本上,你必须为两种方法: find()
和findAll()
在每一个模型,但你也可以搜索使用方法findBy<FieldName>()
和findAllBy<FieldName>()
在举例来说,如果你有db表
notes(id, date, title, body)
并创建该蛋糕模型。 您可以使用诸如findById()
findByTitle()
等。 你只需要首字母大写的数据库字段,你可以做任何领域的搜索快得多。
蛋糕用做它__call()
魔术方法。 如果您正试图执行不存在法这种方法被调用,那么它只是运行find()
或findAll()
与方法的名称和参数动态创造了条件。 这是贯彻落实,可以给你真的有很多好处很简单。
我用__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(),您可以限制哪些键是有效的,如果你不想在你的班上任意“成员”。
一些示例:
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;
有点窝囊,但我认为你可以得到一个想法。 :}
有很多在网络上的例子,使用__get()
和__set()
与私有“属性数组”相结合。 有趣的扭曲我在类定义想要的,是能够实际声明的公共属性和仍然使用这些神奇的拦截器 - 更多的自我记录代码,并给我的IDE做的代码完成,等通常的能力,如果这些属性声明, __get()
和__set()
将不会被调用。 我发现,如果我unset()
那些相同的属性在我的类的构造函数,我能得到两全其美。