Accessors

From: Date: Thu, 19 Feb 2009 07:11:56 +0000
Subject: Accessors
Groups: php.general 
Request: Send a blank email to php-general+get-288592@lists.php.net to get a copy of this message
Hi all. Maybe I'm wanting more Java-like functionality out of PHP, but I don't really like getting and setting members directly (even for public members) - I'd rather use accessors. This way you can control what is getting set and what is returning. However, I also don't really want to create a million get/set accessor methods - this is no fun and takes up a lot of space. After reading around a little bit, it got me thinking about overloading in PHP (which I'm sure we all know is completely different than any other language... but that's another day). I didn't want to use the standard __get and __set methods because that still leaves me with the same notation for getting/setting members. So, instead, I used a close relative of __get and __set. Meet brother __call. Could it really be this trivial to get the notation I'm wanting? Yes. Yes it is. Ok, enough talking... onto the code. <?php class Person {
    public $age;
    private $first, $middle, $last;
    // Gotta have our construct
    public function __construct () {}
    // Here's the fun
    public function __call ($member, $args)
    {
        // Since I know members I want, force the user to only
        // access the ones I've created
        if (property_exists ('Person', $member)) {
            // If args is empty, I must be returning the value
            if (empty ($args)) {
                list ($value) = $this->$member;
                return $value;
            }
            // Oh, args is not empty! Set the value
            $this->$member = $args;
        }
        else {
            // Blow up!
            die ("Fatal Error: Call to undefined member: $member. Exiting...");
        }
    }
} $person = new Person(); // Set the (private) first and last names $person->first('Billy'); $person->last('Bob'); // Get the (private) first and last names echo $person->first() . " " . $person->last()."<br/>"; // Set the (public) age $person->age(103); // Get the (public) age echo "Age: ".$person->age()."<br/>"; // Explosions $person->first = 'Buford'; $person->pizza('Is yummy'); ?> Now if you're reading this and thinking "Duh!" then good for you. However, I know there's at least 1 soul on this list who may benefit from this. But don't stop at the example above. If you want to add validation to the members you're getting/setting, build that into your code. If you want each member to be a specific type, include that as well (I'll leave the implementation up to you). ;-) So let's recap. • This functionality allows me to not have to write 2 accessors for every member • This allows me to use methods instead of directly getting/setting members (even though I can still access public members directly... if I want) • Keeps code consistent and less confusing - I know how to get and set every member What are your thoughts? Does this seem like a reasonable implementation? Useful? Pointless? Hit me up - I can handle *constructive* criticism. But for now, it's late and past my bedtime. Cheers, ~Philip "innerHTML is a string. The DOM is not a string, it's a hierarchal object structure. Shoving a string into an object is impure and similar to wrapping a spaghetti noodle around an orange and calling it lunch."

« previous php.general (#288592) next »