28
Jul
1

PHP Magic __get, __set Methods, and Retaining Private and Protected Properties

I have been making an integration with a complex API with hundreds of potential user provided variables, necessitating me use of PHP’s Magic __get and __set methods.

Unfortunately, by using these methods, PHP’s restriction on private and protected properties is bypassed, making all properties public. This is completely unacceptable from my coding perspective.

This class model overrides the magic __get and __set’s ability to alter and access private and protected properties. Public properties are unaffected. This script also allows the class to set and access private and protected properties.

<?php
 
class setter_getter_respect 
{
 
    private $current_page;
    private $private_properties = array();
 
    public function __construct()
    {
 
        $class = new ReflectionClass(__CLASS__);
        $this->current_page = $class->getFileName();
 
        $class_properties = get_class_vars(__CLASS__);
 
        foreach($class_properties as $class_property_name => $property_value)
        {
            $prop = new ReflectionProperty(__CLASS__, $class_property_name);
 
            if($prop->isPrivate() || $prop->isProtected())
            {
                $this->private_properties[$prop->getName()] = ($prop->isPrivate()) ? 'private' : 'protected';
            }
        }
    }
 
    public function __set($var, $val)
    {
        $requesting_page = debug_backtrace();
 
        if(($requesting_page[0]['file'] != $this->current_page) && (array_key_exists($var,$this->private_properties)))
        {
 
        	trigger_error("Cannot access ".$this->private_properties[$var]." property ".__CLASS__."::".$var." in ".$requesting_page[0]['file']."on line ". $requesting_page[0]['line'],E_USER_ERROR);
 
        }
 
        $this->$var = $val;
    }
 
    public function __get($var)
    {
 
        $requesting_page = debug_backtrace();
 
        if(isset($this->$var)){
 
            if(($requesting_page[0]['file'] != $this->current_page) && (array_key_exists($var,$this->private_properties)))
			{
 
				trigger_error("Cannot access ".$this->private_properties[$var]." property ".__CLASS__."::".$var." in ".$requesting_page[0]['file']."on line ". $requesting_page[0]['line'],E_USER_ERROR);
 
			}
 
            return $this->$var;
 
        } else {
 
            throw new Exception("Required property [" . $var . "] has not been set!");
 
        }
    }
}
 
?>

Extended classes will not have access to __get or __set protected properties. I will alter this snippet when I find a suitable method of handling extended classes.

I’m hoping that php alters the way it handles private and protected properties through the magic methods but until then, this is a way to semi-preserve private and protected properties.

Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
1 Comment:
  1. bhamba 10 May, 2010

    Not good.

Copyright © 2024 SayNoToFlash, Jamie Estep, All Rights Reserved · Theme design by Themes Boutique