This question falls under the theme of this: #
However, my answer is due to the context in which it mentions:
Should I use them in all classes I create?
The answer is simple, the techniques exist to be used but it depends a lot on the cases. There are many authors who refer to magical methods __GET
and __SET
as slower, but the truth is that they can work and we should never stop considering them. I'll 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, by defining 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 $idade > Idade
. The prefixes set
and get
are conventions used in order to make the code readable by anyone. To affect the content and the other to get the content at the time of the method call respectively.
However PHP is a scripting language and implements another mechanism that hurts this protocol, which by many is questionable but has in practice some "much" 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 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 like in the example given, because it is more declarative and is now very useful in today's editors where we write our code. We instantiate an object typing its name and we soon have access to its methods and just choose ... saves a lot of time, not to mention other advantages like standard implementation, etc.
I use the second example when there are many variables. Imagine 10 variables in the class that can increase with implementation ... in the first example you have to put 10 methods SET
and 10 GET
methods. This is a practical example that solves this dimension problem:
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 observe with two simple methods, I can encapsulate an infinite number of variables, which will remain internal. However, since there is no beauty without a snag, , you lose some form of code support and follow the code editors' example, but there are others that can not help you if you mistype variable name, and no errors will ever be returned, which can be a problem in debugging large projects. So:
$teste = new Pessoa();
$teste->nome = "jon";
echo $teste->nome; // mostrará JON
echo $teste->nom; // nada será mostrado
I hope I have explained some useful cases with practical cases without going through exhaustive documentation that can be read elsewhere. With this answer I try to just leave some points that with my experience I have confronted me.