tags:

views:

132

answers:

6

Ok, I have been browsing some php source code and need to know how the following class and sub methods use works:

<?php
$me = new Person;
$me->name("Franky")->surname("Chanyau")->phone("+22", "456 789");
?>

I have pretty solid knowledge of OOP so I don't want a 101. I just need to know how to make the above code possible.

Cheers Franky

+3  A: 

methods name() surname() and phone() return an instance of Person. you can accomplish this by

return $this;

most probably these methods look like this:

public function name($name) {
    $this->name = $name;
    return $this;
}
kgb
+10  A: 

Method chaining is possible, by

return $this;

at the end of the method.

Explained here: phpandstuff: Method Chaining Plus Magic Setters

These methods usually set an instance variable and then just return $this.

public function phone($param) {
  $this->phone = $param;
  return $this;
} 
tilman
+1 for using the keyword chaining.
Shawn Mclean
Ok, so would it also be possible to method chain but instead of returning $this you return another object you created?
Franky Chanyau
@Franky that's possible but strictly speaking Method Chaining returns the host object. Once you start to return different objects, you are going into the direction of a Fluent Interface (to create a DSL). These two are often confused.
Gordon
Yes you can return another object. But from that point onwards, you can't chain methods from object 1, only methods from object 2. --edit: Not sure why you would do that, though.
tilman
Thats some deep stuff. I enjoy learning new things though. I will play around with some code and get back to you soon.
Franky Chanyau
Marking it as accepted answer would really show your appreciation ;)
tilman
Am I right in assuming you can only use method chaining when "setting" properties, rather than "getting" properties? Probably a silly question but clarification would be nice.
Ross
@Ross - It doesn't matter WHAT the method does, as long as it returns the current instance ($this), you can append other methods. Of course, a normal getter function that returns the value of something, wouldnt really work, because it doesnt return $this
tilman
+1  A: 

It's called method chaining. Basically each class function returns the object itself ($this) so that the user can call more functions on the returned object.

public function name() {
    //other stuff...
    return $this;
}

http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html

http://www.electrictoolbox.com/php-method-chaining

Fanis
+2  A: 

like some others said, its a fluid interface http://en.wikipedia.org/wiki/Fluent_interface#PHP the Basic Idea is that a methof of a class always returns the object itself

class Car {
    private $speed;
    private $color;
    private $doors;

    public function setSpeed($speed){
        $this->speed = $speed;
        return $this;
    }

    public function setColor($color) {
        $this->color = $color;
        return $this;
    }

    public function setDoors($doors) {
        $this->doors = $doors;
        return $this;
    }
}

// Fluent interface
$myCar = new Car();
$myCar->setSpeed(100)->setColor('blue')->setDoors(5);

(via wiki)

Hannes
It's not. There is a conceptual difference between *mere* Method Chaining and a Fluent Interface. Method Chaining, by Fowler's definition, returns the Host Object. A Fluent Interface is aimed at creating a DSL. A Fluent Interface can use Method Chains (among other techniques), but a Method Chain is not a Fluent Interface. An example of a Fluent Interface would be `Zend_Db_Table`: `$table->select()->from('foo')->where('bar = baz')->assemble();`
Gordon
you are right, not every time i use Method Chaining its a fluid interface but i wouldn't go so far as to say if thats what he wants to accomplish a a fluid interface or just Method Chaining ...
Hannes
A: 

The idea is if we return $this then we can chain the object method calls together. Here's the solution:

 <?php 

    class Person
    {
        private $strName;
        private $strSurname;
        private $ArrPhone = array();

        public function name($strName)
        {
            $this->strName = $strName;
            return $this; // returns $this i.e Person 
        }

        public function surname($strSurname)
        {
            $this->strSurname = $strSurname;
            return $this; // returns $this i.e Person
        }

        public function phone() 
        {   $this->ArrPhone = func_get_args(); //get arguments as array
            return $this; // returns $this i.e Person
        }

        public function __toString()
        {
            return $this->strName." ".$this->strSurname.", ".implode(" ",$this->ArrPhone);
        }
    }

    $me = new Person;
    echo $me->name("Franky")->surname("Chanyau")->phone("+22", "456 789");

?>
bhu1st
A: 

Correct answers, but to make the code work you should write:

$me = new Person();

instead of

$me = new Person;
Alex
http://php.net/manual/en/language.types.object.php - Actually.. Have a look at official php documentation, they don't use () for instantiating a new object. You would only need the brackets to send variables to the __construct() method of the class.
tilman