This question is part of the subject of: PHP Using Magical or Not Methods?
However, my reply is due to the context of the part where it mentions:
I must use them in every class I create?
The answer is simple, the techniques exist to be used but it depends a lot on the cases. Many are the authors who refer to the magic methods __GET
and __SET
as slower, but the truth is that they can come in handy and we should never stop considering them. I will explain:
class Pessoa {
private $nome;
private $idade;
function getNome() {
return $this->nome;
}
function getIdade() {
return $this->idade;
}
function setNome($nome) {
$this->nome = $nome;
}
function setIdade($idade) {
$this->idade = $idade;
}
}
Let’s imagine this class. It conforms to the definition of object programming also used in other programming languages, which is clearly declarative by the methods it implements. That is, setting for example an internal variable with private
in the class the only way to affect its content is by its unique name methods for $nome > Nome
and to $idade > Idade
. The prefixes set
and get
are conventions used to make the code readable by anyone. To affect the content and the other to obtain the content at the time of the method call respectively.
However PHP and for being a scripting language implements another mechanism that hurts this protocol what for many is questionable but has in practice some "very" utility. Let’s look at an example for the same class:
class Pessoa {
private $nome;
private $idade;
public function __get($name) {
switch (strtolower($name)){
case 'nome':
return $this->nome;
case 'idade':
return $this->idade;
}
}
public function __set($name, $value) {
switch (strtolower($name)){
case 'nome':
$this->nome = $value;
case 'idade':
$this->idade = $value;
}
}
}
$teste = new Pessoa();
$teste->nome = "jon";
echo $teste->nome;
As you can see, the standard has been broken, but the end remains the same. Personally and professionally I think that we should follow the protocol imposed on us by any project, however when we have freedom of implementation I use both depending on some situations.
I use the first example when there are few variables as in the example indicated, for being more declarative and already now for being very useful in today’s editors where we write our code. We instantiate an object we type its name and we have soon access its methods and just choose... saves a lot of time, not to mention other advantages like implementation of standard, etc.
I use the second example when there are many variables. Imagine 10 variables in the class that can increase with the implementation... in the first example you have to put 10 methods SET
and 10 methods GET
. This is a practical example that solves this problem of dimension:
class Pessoa {
private $props = [];
public function __get($name) {
if (isset($this->props[strtolower($name)])) {
return $this->props[strtolower($name)];
} else {
return false;
}
}
public function __set($name, $value) {
$this->props[strtolower($name)] = $value;
}
}
$teste = new Pessoa();
$teste->nome = "jon";
echo $teste->nome;
As you can see with two simple methods I can encapsulate an infinite number of variables, which will remain internal. However and how there is no beauty without a catch, loses some form of support to the code and following the example of the code editors but there are others... these cannot help you if you misspell the variable name and no error will be returned which in debugging in large projects can be a problem. Thus:
$teste = new Pessoa();
$teste->nome = "jon";
echo $teste->nome; // mostrará JON
echo $teste->nom; // nada será mostrado
I hope I have explained with practical cases some usefulness without having gone into exhaustive documentation that can be read elsewhere. With this answer I try to leave only a few points that with my experience I have faced.