PHP Classes and Objects
Calling Methods on an Object Returned by Another Method
Problem
You need to call a method on an object returned by another method.Solution
Call the second method directly from the first:$orange = $fruit->get('citrus')->peel();
Discussion
PHP is smart enough to first call $fruit->get('citrus') and then invoke the peel() method on what’s returned.You can design your classes to facilitate chaining calls repeatedly as if you’re writing a sentence. This is known as a fluent interface. For example:
$tweet = new Tweet;
$tweet->from('@rasmus')
->withStatus('PHP 6 released! #php')
->send();
By stringing together a set of method calls, you build up the Tweet one segment at a time, then send it to the world.
The key is to return $thiswithin every chainable method. That preserves the current context for each subsequent method. Because people can pick and choose which methods to call (and the order they call them), you need one method that always goes last.
In this case, it’s send(). That’s where the logic lives to assemble all the various pieces together and execute what you want done.
This code doesn’t actually send a tweet (as the Twitter API requires OAuth), but is a good illustration of the design practices:
class Tweet {
protected $data;
public function from($from) {
$data['from'] = $from;
return $this;
}
public function withStatus($status) {
$data['status'] = $status;
return $this;
}
public function inReplyToId($id) {
$data['id'] = $id;
return $this;
}
public function send() {
// Generate Twitter API request using info in $data
// POST https://api.twitter.com/1.1/statuses/update.json
// with http_build_query($data)
return $id;
}
}
$tweet = new Tweet;
$id = $tweet->from('@rasmus')
->withStatus('PHP 6 released! #php')
->send();
$reply = new Tweet;
$id2 = $reply->withStatus('I <3 Unicode!')
->from('@a')
->inReplyToId($id)
->send();
Fluent interfaces can be very elegant, but it’s important not to overuse them. They’re best when tied to domains with a well-defined language, such as SQL or sending messages. This example uses a Tweet, but email or SMS would also work.
No comments:
Post a Comment