简体   繁体   中英

PHP Method chaining Confusion

i have been lately introduced to method chaining, and am not sure if what I'm doing here is illegal, or I'm doing it wrong. I have a database Class like:

    class Database
    {
    private $connection;
    private $resultset, $last_query, $current_row;

    function __construct()
    {
        $this->connect();
    }

    public function connect()
    {
        // Connect to the database
    }

    public function query($query)
    {
        $this->last_query = $query;
        $this->resultset = mysql_query($query, $this->connection);
    }

    public function fetchObject()
    {
        $this->current_row = mysql_fetch_object($this->resultset);
        return $this->current_row;
    }
}

I tried using it like:

$db->query("SELECT * FROM users WHERE name='JimmyP'")->fetchObject();

I also tried

$db->fetchObject()->query("SELECT * FROM users WHERE name='JimmyP'");

But i get the error: "Call to a member function fetchObject() on a non-object"

Can someone please explain to me what Im doing incorrectly here as it relates to using method chaining. Thank you.

In query() , you need to return $this otherwise there's nothing to chain it with when the function returns

public function query($query)
{
   $this->last_query = $query;
   $this->resultset = mysql_query($query, $this->connection);
   return $this;  // <- here
}

If you want to using method chaining, what you should do is return $this .

public function query($query)
{
    $this->last_query = $query;
    $this->resultset = mysql_query($query, $this->connection);
    return $this;
}

Then you can do this:

$db->query("SELECT * FROM users WHERE name='JimmyP'")->fetchObject();

Introducing Method Chaining : To enable method chaining in our previous example, we need to add only a single line of code in each 'setXXX' function. And that code is return $this;. Now our class looks like:

class Person
{
    private $name;
    private $age;

    public function setName($Name)
    {
        $this->name = $Name;
        return $this;//Returns object of 'this' i.e Person class
    }

    public function setAge($Age)
    {
        $this->age = $Age;
        return $this;//Again returns object of 'this' i.e Person class
    }

    public function findMe()
    {
        echo "My name is ".$this->name." and I am ".$this->age. " years old.";
    }
}

Now lets access our class methods through method chaining:

$myself = new Person();
$myself->setName('Arvind Bhardwaj')->setAge('22')->findMe();

Explanation of concept:

Surely you're a bit confused about precisely what is going on here. Lets go through this code in an easy way. Before that remember that method chaining always works from left to right!

$myself = new Person() creates a new object of the Person class, quite easy to guess though.

Next, $myself->setName('Arvind Bhardwaj') assigns the name to a variable and returns the object of the same class.

Now $myself->setName('Arvind Bhardwaj') has become an object of the Person class, so we can access the Person class by using $myself->setName('Arvind Bhardwaj') as an object.

Now we set the age as $myself->setName('Arvind Bhardwaj')->setAge('22') . setAge() again returns the object of this class, so the complete phrase $myself->setName('Arvind Bhardwaj')->setAge('22') is now an object of Person.

Finally we print the user information by accessing findMe method as:

$myself->setName('Arvind Bhardwaj')->setAge('22')->findMe();

Method chaining works by returning an object from a function.

$obj = someFunction();
$obj->someMethod();

someFunction returns an object which has a method someMethod , which you can call. Very simple stuff. You can write it like this, without explicitly storing the returned object in a variable:

someFunction()->someMethod();

The ->someMethod() simply works on whatever value someFunction returns.

So to use method chaining, you need to return an object from your methods. An object can also return itself with return $this , so you can chain methods of the same object on itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM