I've had a good look round and can't seem to find an answer to this problem.
Basically I'm using the _call method to dynmically generate get and set methods, however when declaring a variable PHP's default is public. Is there anyway to declare a variable from within a class as protected?
function __call($method, $arguments) {
$prefix = strtolower(substr($method, 0, 3));
$property = strtolower(substr($method, 3));
if (empty($prefix) || empty($property)) {
return;
}
if ($prefix == "get" && isset($this->$property)) {
return $this->$property;
}
if ($prefix == "set") {
$this->$property = $arguments[0];
}
}
One option would be to have a protected array, and to set an element in that array from your magic setter.
class MyClass {
protected $_myProperties = array();
public function __get($name) {
if (isset($this->_myProperties[$name])) {
return $this->_myProperties[$name];
} else {
return null;
}
}
public function __set($name, $value) {
$this->_myProperties[$name] = $value;
}
public function __isset($name) {
return isset($this->_myProperties[$name]);
}
}
First off, I'd HIGHLY suggest not returning
if the prefix or property variables are not set. It will make debugging VERY difficult. Instead, replace the return;
with throw new BadMethodCallException('Method Does Not Exist: '.$method);
Second, isn't that defeating the point of protected variables? It is allowing reading and writing to all properties without any kind of validation. If you're going to do this, you might as well make them public.
I personally find $foo->bar = 'baz';
to be more readable than $foo->setBar('baz');
. Not because it's "easier" to understand, but because the second is unnecessarally verbose.
Personally, I'd suggest doing a __get
and __set
, and adding validation. The whole point of protecting variables is for trust (so that you can trust the settings). Sure, you could use reflection or sub-classing to change them, but I usually assume that if someone goes that far, they deserve to have any unintended concequnces if they mess up a variable.
And keep in mind that if you are using any kind of magic method, you'll need to add documentation elements if you want your IDE to hint the methods/variables to you...
EDIT:
And don't forget, if you declare __get
/__set
methods, you can override them in the child classes. So if the child declares new variables, you can handle them there, and then call parent::__get
to handle the default variables. So don't go with an array just so that you can have one method for all children. Do the validation for the members you know about, and let your children handle their own validation...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With