PHP has _get and _set functions built in. Is it better to write my own get and set functions for each variable or use the built in functions with a ton of if else if? What are the pros and cons of each method?
I tend to go by the rule that if you have complex get or set logic then add a separate get or set method. If you're doing something simple you can leverage __get
or __set
when you would otherwise repeat yourself in a lot of custom get/set methods.
__get
and __set
are magic methods that should usually be used to solve difficult problems rather than to be used as a design basis.
For instance, I found myself on a project where I had to analyze a site that used OOP with deep inheritance (> 2) and one of the important base classes had a public property called name
. However, it also had getters and setters (getName
, setName
) that accessed that property for the mere purpose of getting and setting it. Many classes called getName
and just as many accessed the name
property directly! Not great design.
The magic methods allowed me to solve the problem by renaming the property to _name
and making it private, forcing all requests to the property through the getters and setters.
This being said, there's no need for getters and setters if you're just treating a property like a variable. In that case, just make the property public!
In your case, since there is validating/sanitizing going on, you should employ getters and setters and code them directly as methods (rather than unnecessarily incurring the overhead from the magic methods).
Here is how I handle this problem.
final public function __set($key, $value) {
$method = 'set' . ucfirst($key);
if (method_exists($this, $method)) {
$this->data[$key] = $this->$method($value);
} else {
$this->data[$key] = $value;
}
}
final public function __get($key) {
$method = 'get' . ucfirst($key);
if (method_exists($this, $method)) {
return $this->$method($this->data[$key]);
} else {
return $this->data[$key];
}
}
If you have a custom handler for a property, it gets called (assuming it's named getProperty). Otherwise, the default get/set magic method is used.