Declaring protected variables in methods
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));
$p开发者_C百科roperty = 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...
Is there anyway to declare a variable from within a class as protected?
It doesn't seem so. You can use Reflection to change the accessibility of properties, but it seems that this can only effectively be used to make things public that were not previously public.
You may wish to consider storing automatically generated properties in an an array with the proper visibility.
(There's also __get
and __set
, but they might not fit your needs. They'd only get called when a property is missing or inaccessible. Classes that are able to touch protected properties would bypass them.)
精彩评论