How, when and where to use the magic methods of PHP? Get and Set? What's the difference? Should I use them in all classes I create?

10

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

    
asked by anonymous 12.03.2015 / 02:15

2 answers

4

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.

    
12.03.2015 / 13:25
3

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

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 attribute name is private, in this case nobody can access it beyond the class itself. So how am I going to name it? You are going to set yourself through the setNome () method. It is interesting to do this, because within the setNome, you may want to create business rules, such as a test, if the name is longer than 50 characters give a warning to the user and 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 a maximum of 30 characters in the name, you would simply change the rule in the setNome method, automatically the rule would change in the 50 places, because in all places the name is being set by the method. If you set the value directly in the name attribute and make it public, you would not be able to guarantee that your rule would be enforced 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();
?>
    
12.03.2015 / 13:26