How, when and where to use PHP’s magic methods? Get and Set? What’s the difference? Should I use them in every class I create?

Asked

Viewed 11,707 times

10

I’m starting in POO and would like to know when, where and how I should use the magical methods GET and SET and if possible cite their differences in practice. Should I use them in all the classes I create? How do I know if it’s necessary or not? Could you give me examples?

2 answers

4

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.

2

In object orientation GET and SET are used to encapsulate the class attribute so that it is not directly accessed.

Creating the class:

<?php
 class Aluno(){
    private $nome;

  public function setNome($vNome){
   $this->nome= $vNome;
  }
  public function getNome(){
    return $this->nome;
  }
}
?>

When instantiating this class for example the name attribute is private, in this case no one can access it besides the class itself. So how do I set the name? You will set through the setName() method. It is interesting to do this, because within the setName, you may want to create business rules, such as a test, if the name is greater than 50 characters give a warning to the user and do not accept. Now imagine this class being instantiated in 50 different places within your application, if you had to change this business rule to accept at most 30 characters in the name, you would simply change the rule in the setName method, automatically the rule would change in the 50 places, because everywhere the name is being set by the method. If you set the value directly to the name attribute and made it public, you could not guarantee that your rule would be applied by another developer using this class.

Using the class:

<?php
   include("aluno-class.php");
   $tempAluno = new Aluno(); 
   $tempAluno->setNome("DAVID"); 
   echo "<br/>Nome do Aluno : ".$tempAluno->getNome();
?>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.