为我的所有类实现/扩展/继承/ ...相同的__get和__set函数

时间:2011-06-22 22:38:20

标签: php

我不喜欢像“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;
    }
}

3 个答案:

答案 0 :(得分:2)

如果我理解正确,你想在一组对象中自动处理属性数组,如果是这样,那么这应该是相应的:

abstract class Prototype
{
    protected $properties = array();

    public function __get($key)
    {
        if(property_exists($this,'properties') && is_array($this->properties))
        {
            return isset($this->properties[$key]) ? $this->properties[$key] : null;
        }
    }

    public function __set($key,$value)
    {
        if(property_exists($this,'properties') && is_array($this->properties))
        {
            $this->properties[$key] = $value;
        }
    }
}

这只是一个基本概念,但我刚刚测试过并且工作正常,你可以简单地扩展你的根类:

class User extends Prototype{}

然后使用正常情况下使用get和set magic方法设置值,将方法设置为protected将允许方法的可见性在所有子类中可用,但不允许在对象外部。

这是你在找什么?

答案 1 :(得分:1)

您想要的是traits,但它们在PHP 5.3中不可用。

现在你需要扩展类:

class Foo_Bar extends Foo { }
class Foo extends GetterSetter {}

其中基类是getter / setter类。

答案 2 :(得分:1)

我使用核心类,并从中扩展我的所有其他类;

class xs_Core {
   // generic handling code here
}

class xs_Request extends xs_Core {
   // inherits the generic stuff above
}

和我自己的应用程序特定扩展;

class my_own_special_request extends xs_Request {
   // my stuff
}

必须考虑创建继承的树结构。

说了这么多,有一些东西可以说做魔术的getter和像这样的setter继承整个堆栈,它与查找代码和一般代码中的bug有关保养。几个较大的框架正在回避这种做法,并且已经开始进行大量重写以摆脱沉默失败的诅咒,Joomla现在只是一个更大的例子。我正是因为这个原因重新编写了我自己的框架(xSiteable)。它正在成为一种反模式,所以要谨慎行事。