I'm currently needing to extend a class to add functionality to it (I do not have access to the base class to modify it), and I'm running into an isssue with it.
Basically, I need the magic getter function to return a set of private variables if they are requested, but otherwise default to the default behaviour. I need these properties to be private so as to use the magic setter function to automatically sync some data.
That said, here's some example code:
class newClass extends baseClass {
private $private1;
private $private2;
...
public function __get($name) {
if($name == 'private1') return $this->private1;
if($name == 'private2') return $this->private2;
... (and so on)
// and here, it should default back to it's default behavior (throwing
// an error on getting invalid/inaccessable property, etc.)
// I cannot just use property_exists, because there may or may not be
// private variables in the base class that should not be exposed.
}
public function __set($name,$val) {
// I use this to do some automatic syncing when the two private variables
// above are set. This needs to be triggered, hence the private variables
// in the first place.
}
}
I know, I could use getProperty/setProperty functions, but I would like this to remain as intuitive as possible, despite the argument that performing such operations is counter-intuitive. The two private properties are very much connected to each other. When one of them is set, it is logically going to affect the others.
As of right now, this is the only logical way I can think of to avoid getter/setter functions and maintain the closely bonded sync between properties. If you guys can think of anything else that may be a viable solution, feel free to suggest options :)
PHP does not have a property builtin like other languages, __get and __set are indeed what you should use here. But it's a bit more work to accomplish therefore.
Your problem seems to be property_exists
foremost. It's not easily possible to determine the publicity of properties from within the class (except with introspection). But you can use get_object_vars
to filter out private variables from the base class at least:
function __get($name) {
static $r; if (!isset($r)) { $r = new ReflectionClass($this); }
if (($p = $r->getProperty($name)) and $p->isPublic()) {
return $this->$name;
}
elseif (method_exists($this, "get_$name")) {
return $this->{"get_$name"}();
}
else trigger_error("inaccessible property ->$name", E_USER_NOTICE);
}
For reverting back to default behaviour the best you can do is to manually output an error message.
Don't do this, use getter/setters. They are exactly the same amount of work as what you are doing here.