37

I understand how it works but why would we practically use this?

<?php
    class cat {
        public function __toString() {
            return "This is a cat\n";
        }
    }

    $toby = new cat;
    print $toby;
?>

Isn't this the same as this:

<?php
    class cat {
        public function random_method() {
            echo "This is a cat\n";
        }
    }

    $toby = new cat;
    $toby->random_method();
?>

can't we just use any other public method to output any text? Why do we need magic method like this one?

nbro
  • 15,395
  • 32
  • 113
  • 196
Stann
  • 13,518
  • 19
  • 65
  • 73

11 Answers11

28

You don't "need" it. But defining it allows your object to be implicitly converted to string, which is convenient.

Having member functions that echo directly is considered poor form because it gives too much control of the output to the class itself. You want to return strings from member functions, and let the caller decide what to do with them: whether to store them in a variable, or echo them out, or whatever. Using the magic function means you don't need the explicit function call to do this.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    How do you invoke this method to store them in a var. If you had a class called StringClass could you do it like this? `$stringClass = new StringClass(); $string = (string) $stringClass` . As just assigning `$string = $stringClass` would assign the object. – SamBremner Jan 25 '18 at 10:45
  • @SamBremner: That looks reasonable as a way to trigger the conversion _explicitly_ (try it and see what happens!). But the real power is in the implicit conversion, otherwise you might as well just create your own `toString()` function, or a similar function with any other name). – Lightness Races in Orbit Jan 25 '18 at 21:22
21

In addition to all existing answers, here's an example, :

class Assets{

  protected 
    $queue = array();

  public function add($script){
    $this->queue[] = $script;
  }

  public function __toString(){    
    $output = '';    
    foreach($this->queue as $script){
      $output .= '<script src="'.$script.'"></script>';
    }    
    return $output;
  }

}


$scripts = new Assets();

It's a simple class that helps you manage javascripts. You would register new scripts by calling $scripts->add('...').

Then to process the queue and print all registered scripts simply call print $scripts;.

Obviously this class is pointless in this form, but if you implement asset dependency, versioning, checks for duplicate inclusions etc., it starts to make sense (example).

The basic idea is that the main purpose of this object is to create a string (HTML), so the use of __toString in this case is convenient...

nice ass
  • 16,471
  • 7
  • 50
  • 89
8

__toString() is called when an object is passed to a function (esp echo() or print()) when its context is expected to be a string. Since an object is not a string, the __toString() handles the transformation of the object into some string representation.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
5

It's just a standardized method to produce a string representation of an object. Your random_method approach works if you assume all objects in your program uses that same method, which might not be the case if you use third party libraries.

You don't need the magic method, but it provides convenience, as you'll never really have to call it explicitly.

Also, if PHP should internally ever want to turn your object into text, it knows how to do that.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
falstro
  • 34,597
  • 9
  • 72
  • 86
4

The __toString method allows a class to decide how it will react when it is treated like a string

http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring

John Giotta
  • 16,432
  • 7
  • 52
  • 82
3

__toString allows you to define the output when your object is converted to a string. This means that you can print the object itself, rather than the return value of a function.

Have a look at below example:

<?php

class Student 
{
    protected $name;
    protected $age;

public function getName(){
    return $this->name;
}

public function getAge(){
    return $this->age;
}

private function setName($name){
     $this->name = $name;
}

private function setAge($age){
    $this->age = $age;
}


public function __construct($name, $age) {
    $this->setName($name);
    $this->setAge($age);
}

public function __toString(){
    return "hello ". $this->getName(). " my age is ". $this->getAge();
}

}

$obj = new Student("Sajib", 23);
echo $obj;
S_K
  • 31
  • 5
2

__toString allows you to define the output when your object is converted to a string. This means that you can print the object itself, rather than the return value of a function. This is frequently more convenient. See the manual entry.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
1

Using __toString() overrides the operator that is called when you print objects of that class, so it makes it easier for you to configure how an object of that class should be displayed.

Dan
  • 3,490
  • 2
  • 22
  • 27
  • There isn't any operator overloading/overriding. The method is called whenever the object is converted to a string. – BoltClock Mar 02 '11 at 19:23
1

__String helps us it returning error message in case there is some error in constructor.

Following dummy code will clarify it better. Here if creation of object is failed, an error string is sent:

class Human{
   private $fatherHuman;
   private $errorMessage ="";
   function __construct($father){
         $errorMessage = $this->fatherHuman($father);
   }

   function fatherHuman($father){
        if($father qualified to be father){
            $fatherHuman = $father;
            return "Object Created";//You can have more detailed string info on the created object like "This guy is son of $fatherHuman->name"
         } else {
            return "DNA failed to match :P";
         }
    }
}

function run(){
   if(ctype_alpha($Rahul = Human(KingKong)){
        echo $Rahul;
   }

}

run();   // displays DNA failed to match :P
ayushi
  • 63
  • 1
  • 6
0

You don't have to specifically call the toString method. When ever you print the object toString is being called implicitly. Any other method would have to be called explicitly.

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
-6

it's like override with c# :

class Person

{

public Person(string firstName, string lastName)

{

FirstName = firstName;

LastName = lastName;

}

public string FirstName { get; set; }

public string LastName { get; set; }

public override string ToString()

{

return FirstName + “ “ + LastName;

}

}
FAREH
  • 31
  • 6