Property of a method in another method

1

I have searched the problem, but I have not been able to solve it. I'm starting with PHP object-oriented and I'm having a question.

class Correios{
    public $nome_do_user;

        public function RecebeJson(){
            $json = file_get_contents('php://input');
            $dados = json_decode($json, TRUE);
            $this->nome_do_user = $dados['message']['from']['first_name'];
        }       

        public function getUser(){
            $this->nome_do_user;
        }

        public function viewthis(){
            var_dump($this);
        }

}   

$correios = new Correios();
$correios->getUser();
$correios->viewthis();

That is: I get a JSON with the user name and store it in $this->nome_do_user . However, I want to call it in the getUser method, but in this method, nome_do_user no longer exists in $this (I realized via var_dump ).

So when I call via getUser , nothing is returned

Where am I going wrong? I set the property in the first method because it does not pass the second?

    
asked by anonymous 03.04.2016 / 22:14

2 answers

0

It is not feasible to try to fix the code you posted because OOP is conceptual and depends on how the structure of the other system codes you are developing is.

In the code you posted there is the classic getter of getter and setter (popular term). The technical name is "accessors and mutators".

However, it is applied redundantly because the nome_do_user queue property is set to public. That is, it can be freely accessed without accessors or can be freely modified without mutators .

$correios = new Correios();
var_dump($correios->nome_do_user);

To fix and get to a more appropriate path in object-oriented programming, try to understand the basics of defining visibility of properties and methods: link

Example with accessors and mutators (getter and setter)

Returning to the code, even if you invoke $correios->nome_do_user , you still will not get anything from nome_do_user since it has not been set.

To set, invoke method RecebeJson() before accessing nome_do_user :

$correios = new Correios();
$correios->RecebeJson();
var_dump($correios->nome_do_user);

Okay, it worked! But it did not resolve anything in OOP itself.

class Correios
{

    /*
    Definimos com visibilidade privada, para que seja acessível somente dentro desse objeto Correios.
    */
    private $nome_do_user = null;

    public function setNomeUser()
    {
        /*
        Uma condicional que verifica se está vazio. Isso evita executar a rotina mais de uma vez.
        A lógica aqui é que se já foi executado, provavelmente não precisa executar mais vezes pois apenas estaria consumindo processos.
        */
        if ($this->nome_do_user === null) {
            $this->nome_do_user = json_decode(file_get_contents('php://input'), true);
        }
    }

    /*
    Accessor que retorna a propriedade nome_do_user.
    */
    public function getNomeUser()
    {
        return $this->nome_do_user;
    }

}

$correios = new Correios();
$correios->setNomeUser();
var_dump($correios->getNomeUser());

As you can see, in practice, a lot has been modified from the original.

Example suppressing the mutator (setter)

Personally speaking, despite trying to figure out a way to correct, I feel uncomfortable because it does not mean that this is correct or the best thing to do, because as I said at the outset, OOP is conceptual. It is a set of paradigms. But we will not enter into this discussion because it is something very extensive. Let us then go on to a new suggestion to improve, or optimize, this class:

What bothers me about this class is that it does not seem to make sense to use a mutator . In this case setNomeUser() . We can simplify this way:

class Correios
{

    /*
    Definimos com visibilidade privada, para que seja acessível somente dentro desse objeto Correios.
    */
    private $nome_do_user = null;

    public function getNomeUser()
    {
        /*
        Uma condicional que verifica se está vazio. Isso evita executar a rotina mais de uma vez.
        A lógica aqui é que se já foi executado, provavelmente não precisa executar mais vezes pois apenas estaria consumindo processos.
        */
        if ($this->nome_do_user === null) {
            $this->nome_do_user = json_decode(file_get_contents('php://input'), true);
        }
        return $this->nome_do_user;
    }

}

$correios = new Correios();
var_dump($correios->getNomeUser());

This may not be ideal for your project, however, because it depends on planning, what you plan to implement in this class.

In spite of this, note that we now move away from the "getter and setter" (accessor and mutator) pattern and are creating a new pattern.

The points you should note is, is the conceptual pattern you are creating something that is widely recognized and accepted by developer communities?

Even though it is a pattern different from the already existing and widely recognized standards, can I create a pattern of my own?

As long as it is well documented, yes. And of course as long as it's consistent, well written.

Example with constructors

Let's go to a third example of how to "refine" or "complicate" what is already complicated.

class Correios
{

    /*
    Definimos com visibilidade privada, para que seja acessível somente dentro desse objeto Correios.
    */
    private $nome_do_user = null;

    public function __construct()
    {
        /*
        Uma condicional que verifica se está vazio. Isso evita executar a rotina mais de uma vez.
        A lógica aqui é que se já foi executado, provavelmente não precisa executar mais vezes pois apenas estaria consumindo processos.
        */
        if ($this->nome_do_user === null) {
            $this->nome_do_user = json_decode(file_get_contents('php://input'), true);
        }
        return $this;
    }

    public function getNomeUser()
    {
        return $this->nome_do_user;
    }

}

$correios = new Correios();
var_dump($correios->getNomeUser());

In practice, it does the same as the second example. The difference is that we use the constructor method. __construct() .

The __construct() method is invoked automatically whenever a new instance of a class starts.

That is, whenever you do $var = new NomeDaClasse() , if there is a method called __construct() , it will run automatically. See: link

Static Methods

Now let's "radicalize" and show this whole thing with static methods.

class Correios
{
    private static $nome_do_user = null;
    public static getNomeUser()
    {
        /*
        Uma condicional que verifica se está vazio. Isso evita executar a rotina mais de uma vez.
        A lógica aqui é que se já foi executado, provavelmente não precisa executar mais vezes pois apenas estaria consumindo processos.
        */
        if (self::$nome_do_user === null) {
            self::$nome_do_user = json_decode(file_get_contents('php://input'), true);
        }
        return self::$nome_do_user;
    }
}

var_dump(Correios::getNomeUser());

When to use static methods and properties?

The thing that seemed simple goes deeper into very complex subjects.

You may think it's much cleaner to visually invoke Correios::getNomeUser(); instead of

$correios = new Correios();
$correios->getNomeUser();

After all, if I can get the same result with a smaller code, is this the one I should use?

Performatically, static style is better than instantiating an object?

With each question, you will probably create new questions. So the complexity in guiding you what or which way to go.

Final Consideration

Despite criticisms and advice on existing responses and comments, do not be discouraged. Every good programmer started as you did, writing concept codes without knowing exactly what he was doing. By practicing a lot and studying, you will be able to understand how to use it properly.

I could still demonstrate some 5 different ways, but I believe that until now it is enough for you to understand and choose what you really want to use. But I agree with what they quoted. Avoid using miraculous OOP things if you do not understand what you are doing. In a nutshell, look for the basic step that is the definition of visibility (public, protected, private).

    
04.04.2016 / 04:58
3

Some considerations

OOP by itself does not solve any problem. Many cases where one tries to use OOP would be better off without this paradigm. Knowing what you are doing, thinking about the problem, understanding the requirements and applying them correctly in the code is what makes the difference. Everyone who says that OOP does this or that is selling an idea. Doing OOP or otherwise is going to make the code good.

It's strange to have% public% and have a method to get its value. It seems redundant. It may be that there is a reason in the future, but it is not yet clear when to use one or the other to get the username. But if you're going to use OOP (I'm not saying it should), the attributes should be private and accessed by some method.

Using an uninitialized member will be a problem.

Creating some form of access to something that is not guaranteed initialized is not OOP or anything else, it is wrong programming. An object must not have a transient state. It may be that one day it can evolve and show the need for a class, but at the moment it is only causing confusion. It would be so much simpler to have a function that does what it has to do, returns a result and that's it.

The solution

If you still want to insist on this you have to ensure that the status is valid before using. If you're not have to report this, I do not know, maybe throwing an exception. But I do not see this with good eyes, it still seems like wrong programming, it seems like an artificial solution because you're using the wrong tool.

A slightly better solution would be to have a constructor that would guarantee that either it has the state of the object in order or it does not create the object. In this particular case it continues to sound like gambiarra, but it is a bit better because it can avoid the exception. It's no use creating a builder and letting the object be created when there are problems during creation.

Note that the code works when used correctly (OOP is creating difficulty rather than ease), although I had to organize and make some adjustments . For example, $nome_do_user was missing in method return . I could have made other changes. I find the mixture of Portuguese and English curious. The class name itself does not seem to reflect what it does. It may seem silly but these things indicate that the class is being assembled without thinking. OOP also has a lot to do with giving correct names to every thing. And I hope getUser() is only there temporarily for a test.

The problem with this code is that there is a situation where the result is not as expected, which can always happen and this situation is not being addressed properly. When something fails, the code needs to reflect this.

Conclusion

I will not try to redo this class to be right, because it as a whole is the wrong tool. I do not like teaching to do something deep down that's wrong just to please a taste.

I insist that a simple function that returns the result or a null value if it is not possible to give a result would be enough.

    
03.04.2016 / 22:57