开发者

Implement/extend/inherit/... the same __get and __set function for all my classes

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


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?


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜