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

发布于 2024-11-16 21:07:57 字数 1766 浏览 0 评论 0原文

我不喜欢“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧梦荧光笔 2024-11-23 21:07:57

如果我理解正确,您希望自动处理一组对象中的属性数组,如果是这样,那么这应该相应地工作:

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 魔术方法设置值一样使用,将方法设置为 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:

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;
        }
    }
}

This is just a basic concept but I have just tested and work's fine, you simple extend your root classes like so:

class User extends Prototype{}

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?

娜些时光,永不杰束 2024-11-23 21:07:57

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

现在您需要扩展如下类:

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

其中基类是您的 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:

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

where the base class is your getter/setter class.

鸠书 2024-11-23 21:07:57

我使用一个核心类,并从它扩展所有其他类;

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 继承,这与查找代码中的错误和一般代码维护有关。几个较大的框架正在回避这种做法,并且已经开始进行大规模重写以摆脱无声失败的诅咒,Joomla 目前只是一个更大的例子。正是出于这个原因,我刚刚重新编写了自己的框架(xSiteable)。它正在成为一种反模式,所以要小心行事。

I use a core class, and extend all my other classes from it ;

class xs_Core {
   // generic handling code here
}

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

and my own application-specific extensions ;

class my_own_special_request extends xs_Request {
   // my stuff
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文