为我的所有类实现/扩展/继承/...相同的 __get 和 __set 函数
我不喜欢“getProperty”和“setProperty”等函数,因此我研究了 __get 和 __set 函数。
我创建了一个运行良好的结构。现在我想在我的大部分课程中使用它。我该如何做到这一点(记住我可能想用另一个类扩展一个类)而不必重复代码?
我已经知道接口不是一个选项,因为这都是关于复制代码的(如果我理解正确的话)
以下是函数,以防万一:
/**
* Simply return the property
*/
private function __get($strProperty) {
if(array_key_exists($strProperty, $this->properties)){
$c = $this->properties[$strProperty];
// Fetch the wanted data and store it in memory
if(!$c['fetched']){
if($c['type'] == 'array'){
$proptr = $this->md->fetch_array('SELECT ' . $c['field'] . ' FROM ' . $c['table'] . ' WHERE ' . $c['where'], $c['table'].$c['field'].$c['where'], 1000);
$c['value'] = $proptr;
}else {
$proptr = $this->md->query_first('SELECT ' . $c['field'] . ' FROM ' . $c['table'] . ' WHERE ' . $c['where'], $c['table'].$c['field'].$c['where'], 1000);
$c['value'] = $proptr[$c['field']];
}
}
return $c['value'];
} else {
return $this->$strProperty;
}
}
/**
* Set the property, and update the database when needed
*/
private function __set($strProperty, $varValue) {
// If the property is defined in the $properties array, do something special
if (array_key_exists($strProperty, $this->properties)) {
// Get the fieldname
$field = $this->properties[$strProperty]['field'];
$data[$field] = $varValue;
$this->md->update(TABLE_USER, $data, $this->properties[$strProperty]['where']);
// And store the value here, too
$this->$strProperty = $varValue;
} else {
$this->$strProperty = $varValue;
}
}
I do not like functions like "getProperty" and "setProperty", so I looked into the __get and __set functions.
I created a structure that works quite well. Now I want to use it in most of my classes. How do I do this (keeping in mind I might want to extend a class with another class) without having to duplicate code?
I already know an interface is not an option, as that's all about duplicating code (if I understand it correctly)
Here are the functions, just in case:
/**
* Simply return the property
*/
private function __get($strProperty) {
if(array_key_exists($strProperty, $this->properties)){
$c = $this->properties[$strProperty];
// Fetch the wanted data and store it in memory
if(!$c['fetched']){
if($c['type'] == 'array'){
$proptr = $this->md->fetch_array('SELECT ' . $c['field'] . ' FROM ' . $c['table'] . ' WHERE ' . $c['where'], $c['table'].$c['field'].$c['where'], 1000);
$c['value'] = $proptr;
}else {
$proptr = $this->md->query_first('SELECT ' . $c['field'] . ' FROM ' . $c['table'] . ' WHERE ' . $c['where'], $c['table'].$c['field'].$c['where'], 1000);
$c['value'] = $proptr[$c['field']];
}
}
return $c['value'];
} else {
return $this->$strProperty;
}
}
/**
* Set the property, and update the database when needed
*/
private function __set($strProperty, $varValue) {
// If the property is defined in the $properties array, do something special
if (array_key_exists($strProperty, $this->properties)) {
// Get the fieldname
$field = $this->properties[$strProperty]['field'];
$data[$field] = $varValue;
$this->md->update(TABLE_USER, $data, $this->properties[$strProperty]['where']);
// And store the value here, too
$this->$strProperty = $varValue;
} else {
$this->$strProperty = $varValue;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果我理解正确,您希望自动处理一组对象中的属性数组,如果是这样,那么这应该相应地工作:
这只是一个基本概念,但我刚刚测试过并且工作正常,您只需扩展您的根像这样的类:
然后像通常使用 get 和 set 魔术方法设置值一样使用,将方法设置为 protected 将允许方法的可见性在所有子类中可用,但不允许在对象外部使用。
这是您要找的吗?
If I understand you correctly you would like to automate the handing of the property array within a set of objects, if so then this should work accordingly:
This is just a basic concept but I have just tested and work's fine, you simple extend your root classes like so:
and then use as you would normally set values using get and set magic methods, setting the methods to protected will allow the visibility of the methods to be available in all child classes but will not be allowed outside the object.
Is this what you was looking for?
您想要的是 traits,但它们在 PHP 5.3 中不可用。
现在您需要扩展如下类:
其中基类是您的 getter/setter 类。
What you want are traits, but they aren't available in PHP 5.3.
For now you'll need to extend classes like:
where the base class is your getter/setter class.
我使用一个核心类,并从它扩展所有其他类;
以及我自己的特定于应用程序的扩展;
人们必须考虑创建继承的树形结构。
说了这么多,有一点要说的是,不要在整个堆栈中进行像这样的神奇 getter 和 setter 继承,这与查找代码中的错误和一般代码维护有关。几个较大的框架正在回避这种做法,并且已经开始进行大规模重写以摆脱无声失败的诅咒,Joomla 目前只是一个更大的例子。正是出于这个原因,我刚刚重新编写了自己的框架(xSiteable)。它正在成为一种反模式,所以要小心行事。
I use a core class, and extend all my other classes from it ;
and my own application-specific extensions ;
One has to think in terms of creating a tree-structure of inheritance.
Having said all that, there's something to be said for not doing the magic getters and setters like this inherit all through the stack, and it has to do with finding bugs in your code and general code maintenance. Several larger frameworks are shunning this practice, and large re-writes have been initiated to rid it from the curse of silent failure, Joomla just being a larger example right now. I just re-wrote my own framework (xSiteable) for exactly this reason, as well. It's becoming an anti-pattern, so tread carefully.