Property of a method in another method

Asked

Viewed 303 times

0

I have been researching about the problem, but I couldn’t solve it. I’m starting with object-oriented PHP 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 receive a JSON with the user name and store on $this->nome_do_user. But I wish to call you in the method getUser, but in this method, nome_do_user no longer exists in the $this (I saw var_dump).

So when I call him I see getUser, nothing is returned

Where am I missing? I set the property in the first method, because it does not pass to the second?

  • You’re not calling the method RecebeJson before calling getUser. The variable does not exist yet. If you want it to be available in the creation of the object, create a constructor(__construct(){}) and start him on the Receive method.

  • I did it this way, I created a constructor and it calls Recebejson.. Then I tried to display the user via $correios->getUser();, but it still hasn’t been done yet...

  • In php the constructor is a method previously defined as function __construct(){}.

  • Yeah, just like I did....

2 answers

3

Some considerations

OOP alone does not solve any problem. Many cases where one keeps trying to use OOP would be better without this paradigm. Knowing what you’re 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 other right way is that it will make the code look good.

It’s strange to have $nome_do_user public and having a method to take its value, seems redundant. There may be a reason in the future, but it’s still unclear when to use one or the other to get the user’s name. But if you’re going to use OOP (I’m not saying you should), the attributes should be private and accessed by some method.

Using an uninitialized member will be a problem even.

Creating some form of access to something that’s not guaranteed to be initialized is not OOP or anything else, it’s wrong programming. An object should not have a transient state. It may be that one day this may 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 make sure the status is valid before you use it. If you’re not, you have to report it, I don’t know, maybe make an exception. But I don’t see it with good eyes, it still looks like wrong programming, looks like artificial solution because it’s using the wrong tool.

A slightly better solution would be to have a constructor who would guarantee that either has the state of the object in order or not create the object. In this particular case it still seems like gambiarra, but it’s a little better because it can avoid the exception. No use creating a constructor 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 needed to organize and make some adjustments. For example, one was missing return in the method getUser(). I could have made other changes. I find curious the mixture of Portuguese and English. The class name itself does not seem to reflect what it does. It may sound silly but these things indicate that the class is being mounted without thinking. OOP also has a lot to do with giving correct names to every thing. And I hope that viewthis() be there only temporarily for a test.

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

Completion

I’m not going to try to remake this class to be right, because it as a whole is the wrong tool. I don’t like teaching to do something that deep down is 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.

  • 2

    Thank you very much for the great explanation. I am now starting my studies in POO and had already noticed some of the points you quoted. Without object orientation, I would have done it already, but I preferred this way to train my learning. I usually do this mixture of Portuguese and English sometimes, but I wouldn’t do it if the code wasn’t just mine, rs... And yes, I will remove the viewthis kkk. Well, the code now works, I realized where I was going wrong, trying to use a var not yet called and forgot a Return... Thank you all !

0


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

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 in a redundant way, as the property nome_do_user is defined as public. That is, it can be accessed freely without accessors or can be modified freely without mutators.

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

To correct and arrive at a more suitable path in object-oriented programming, try to understand the basic definition of visibility of properties and methods: http://php.net/manual/en/language.oop5.visibility.php

Example with accessors and mutators (getter and Setter)

Returning to code, even if it summons $correios->nome_do_user, you still won’t get anything from nome_do_user because it was not set.

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

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

Okay, it worked! But it didn’t solve anything in OOP properly speaking.

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, much has been modified from the original.

Example deleting the mutator (Setter)

Speaking personally, despite the attempt to demonstrate a way to correct, I feel uncomfortable because it does not mean that this is correct or the best to do, because as I said at the beginning, OOP is conceptual. It’s a set of paradigms. But let’s not get into this discussion because it’s something very extensive. Let’s go to a new suggestion to improve, or optimize this class:

What bothers me about this class is that the use of a mutator. In that case setNomeUser(). We can simplify it like this:

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());

Still this may not be ideal for your project, because it depends on planning, what else you intend to implement in this class.

Despite this, note that we are now leaving the "getter and Setter" pattern (accessor and mutator) and creating a new standard.

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

Even if it’s a different pattern from existing and widely recognized standards, I can create a pattern of my own?

As long as it’s well-documented, yes. And obviously as long as it’s consistent, and 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 method __construct() is automatically invoked every time you start a new instance of a class.

That is, whenever you do $var = new NomeDaClasse(), if there is a method called __construct(), this will be executed automatically. See: http://php.net/manual/en/language.oop5.decon.php

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 matters.

You may think it’s much cleaner visually invoking Correios::getNomeUser(); instead of

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

After all, if I can get the same result with a smaller code, this is 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 path to follow.

Final consideration

Despite the criticisms and advice in the existing responses and comments, do not be discouraged. Every good programmer started out like you, writing conceptual code without knowing what exactly you were doing. Over time, practicing hard and studying, you will be able to understand how to use properly.

I could still demonstrate 5 more different ways, but I believe that so far is enough for you to understand and choose what you really want to use. But I agree with what they quoted. Avoid using OOP mirabulant things if you don’t understand what you’re doing. In a summary, look for the basic step that is the definition of visibility (public, protected, private).

  • Thank you so much for your help! I will read carefully about visibility. Thanks!

Browser other questions tagged

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