How to use an object to add to an attribute?

Asked

Viewed 1,335 times

7

When I do the code below you get this error:

Object of class Client could not be converted to string in ... animal.class.php

In this part does not allow me to pass an object to be used in the property "owner"

$dog = new Cachorro('Rex',$ana);

But when I use string 'ana' ex.:

$dog = new Cachorro('Rex','ana');

works normally and returns me the "ana" as owner of the animal

//classe Cliente
class Cliente{
    public $nome;

public function __construct($nome){
        $this->nome     = $nome;
    }
}

abstract Animal{
    protected $nome;
    protected $dono;

   public function __construct($nome,$dono){
       $this->nome      = $nome;
       $this->dono  = $dono;
   }

  public function getDono(){
        return $this->dono ;
    }
}
//Essa classe foi implementada, porém nada está afetando e a deixei "isolei" para ter   certeza
class Cachorro extends Animal{

}

$ana = new Cliente('ana');
$dog = new Cachorro('Rex','ana' );
echo "Dono: ". $dog->getDono();

3 answers

8

You are adding one Object (class Customer) to variable $ana

$ana = new Cliente('ana');

So here $this->dono = $dono; receives an object (and not a string)

public function __construct($nome,$dono){
   $this->nome  = $nome;
   $this->dono  = $dono;
}

The moment you try to print with echo the method getDono() he will send the variable $this->dono which you previously set as the "Ana class" (an object)

public function getDono(){
    return $this->dono; //Retorna o objeto
}

The right thing would be:

echo "Dono: ". $dog->getDono()->nome;

Or so:

$ana = new Cliente('ana');
$dog = new Cachorro('Rex', $ana->nome);
echo "Dono: ". $dog->getDono();

You can also make the variable name in private (or protected) and create a method to catch her, thus preventing that accidentally someone seven a value to her out of class:

class Cliente {
    private $nome;

    public function __construct($nome){
        $this->nome     = $nome;
    }

    public function getNome(){
        return $this->nome;
    }
}

and use in this way:

$ana = new Cliente('ana');
$dog = new Cachorro('Rex', $ana->getNome());
echo "Dono: ". $dog->getDono();
  • our worked as I wished, but now I was in doubt what is the correct and most advisable form, whether yours or @sergiopereira (answer from above) ? not that I’m belittling you

  • @Leandromacedo the answer of Spain is just a "magic" method, I disagree with Sergio, because there are better and easier ways for those who use the class, the best is to work with a method get (ex: public function getNome() { return $this->nome; }) (in my opinion). I personally find my answer more correct.

8


I’ll answer since you have divergent answers and do not know what to do.

You have already learned in the other answers that there is a type compatibility problem. Under normal conditions you cannot print the content of a complex type in general that you have created. no component knows how to print this dataset. You, the type creator need to "teach" the application of how to do this. You are always worried about doing the right thing and this is right. Every class should take responsibility for everything that refers to it.

Then create the method __tostring(), as defined by the reply of sergiopereira, it is not only useful, it is almost mandatory. In fact some programming languages even require it. Or at least provide a standard method to do this for all classes (the way to do this varies depending on the philosophy of the language).

In fact Guilherme Nascimento is right to call this method magical but has no problem in using it. The builder is also magical. There is and should not even any rule to prevent its use. On the contrary, these are desirable methods in certain situations.

You like to do the right thing. So ask yourself: when do you build an instance of Cachorro you mean she is associated with a owner or to a owner name? It seems that his initial intention was to use the first form. And I think it’s better. It is not wrong to put only one owner name on the dog if you wish but I think dogs have full owners. How to pass the name you have only the name, does not really associate to the owner. In most situations it is not what you need. I would dismiss any solution upon name.

So your initial solution was correct. The error was in accessing the owner. You tried to print the owner and the application didn’t know how.

If your intention was to explicitly print the owner’s name, then you should ask to print the owner’s name and not to print the owner. It may sound silly but conceptualizing things correctly in programming is fundamental. If you don’t define precisely what you want to do, you won’t be able to express in code correctly.

So the two answers are correct, they just didn’t explain to you when and why to use each one. I would use both.

class Cliente {
    private $nome;
    public function __construct($nome) {
        $this->nome = $nome;
    }
    public function getNome() {
        return $this->nome;
    }
    public function __toString() {
        return $this->nome;
    }
}
abstract class Animal {
    protected $nome;
    protected $dono;
    public function __construct($nome, $dono) {
       $this->nome = $nome;
       $this->dono = $dono;
   }
    public function getDono() {
        return $this->dono;
    }
}
class Cachorro extends Animal {
    public function __construct($nome, $dono) {
       parent::__construct($nome, $dono);
   }
}
$ana = new Cliente('ana');
$dog = new Cachorro('Rex', $ana);
echo "Dono: " . $dog->getDono();
echo "\nNome do dono: " . $dog->getDono()->getNome();

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Note that I had the owner and the name of the owner printed out. By chance the result is the same, but take it as a mere fluke. In the future each technique can give different results.


As you want to learn I will take this opportunity to tell you to avoid obvious comments like saying that class is Cliente is the class Cliente. You saw how obvious? Comments should say why and not what.

Also try to keep code with consistent organization. It may sound silly but it’s critical to do this. You visualize it better. People who will work with your code, including here better visualize. You start organizing your thoughts in a more organized way.

I’m saying this because it doesn’t seem to be your case but there are novice programmers who are stubborn, who think this is nonsense. And they spend their whole lives doing everything wrong and they never learn to make quality code. I’ve never known in my more than 30 years of experience a good programmer who didn’t care about these details. There are even those who defend the website should serve users anyway, without organization. These people do not understand that they are providing a disservice to users. They are not helping programmers to evolve as needed. Originally the goal of the websites Stackexchange was to make everyone learn, to be different from the forums that only provided solutions. And then the programmers are like the last graph of that page (according to my experience the graphics seem to me quite close to reality in most cases).

I’m not a fan of the term attribute, I prefer field.

  • Good morning @bigown I didn’t explain about _tostring why this isn’t in the question and I didn’t say it’s a magical method referring to me as if it were something wrong, only by his code it seems to me that he is "learning" about object orientation , so my answer fully covers the question and makes the most correct.

  • 2

    @Guilhermenascimento I agree, even did not say that his answer was wrong. Only to say that his answer is the more correct It’s a huge push. I don’t think it is, even though it is perfectly correct it induces the use of the owner’s name and does not give an alternative to what he is trying to do. I would reiterate that this is not a problem, but it is an answer that does not expose everything that it could. But if you’re trying to tell the AP that he must accept your answer, this will be his decision after his analysis, it’s not up to you to decide for him.

  • It’s not that bigown, I didn’t say he’s obliged to accept my answer; I don’t think it’s push hard why I explained about a use in object orientation; I don’t see why __toString() should be part of my answer and or explain about it, being that it is not the focus of his question.

  • thanks to everyone who helped me, as much as I didn’t schedule your response, but they helped me a lot !!

  • @bigown thanks for the suggestion, vc have some material so I can learn to keep the code more organized and consistent ?

  • @Leandromacedo have nothing specific, you can start here http://answall.com/questions/tagged/stilo-coding%C3%A7%C3%A3o. But I’m talking about even basic things like indenting blocks, giving spacing that makes visualization easier. But the reason I have spoken is that it lacks consistency, that is, every moment you do it in a way. Your concern is only whether you perform or not. Analyze your code character by character and see how it differs. It doesn’t hurt the code strongly but creates a pattern of decompression. I’m only saying this because I realize you want the best.

Show 1 more comment

6

Try to add a method __toString to his class Cliente, guy:

public function __toString() {
    return $this->nome;
}

So you can pass $ana in place of 'ana' hassle-free:

$ana = new Cliente('ana');
$dog = new Cachorro('Rex', $ana);
echo "Dono: ". $dog->getDono();
  • ok, it worked perfectly. Thank you very much!! this is the best way or the one presented by @Guilherme Ferreira (the bottom answer) is the ideal ?

  • I find this way the most useful but it depends a lot on how you want to use the objects Cliente in your application. In your original problem you want to concatenate a string ("Dono: ") with an object Cliente. What did you want the result to be? Appear the name of the owner? The word "Cliente"? PHP cannot guess the expected result, so you can be more explicit as $dog->getDono()->getNome() or use __toString() as a shortcut. The __toString() can still help later when you are debugging something. I would say it is a good practice.

  • i expected to receive the name of "owner"

Browser other questions tagged

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