PHP方法链接?

我正在使用PHP 5,并且我听说过面向对象方法中的一个新function,称为“方法链接”。 究竟是什么? 我如何实现它?

它真的很简单,你有一系列的mutator方法,都返回原始(或其他)的对象,这样你可以保持调用函数。

<?php class fakeString { private $str; function __construct() { $this->str = ""; } function addA() { $this->str .= "a"; return $this; } function addB() { $this->str .= "b"; return $this; } function getStr() { return $this->str; } } $a = new fakeString(); echo $a->addA()->addB()->getStr(); 

这输出“ab”

基本上,你拿一个对象:

 $obj = new ObjectWithChainableMethods(); 

调用一个有效地return $this; 最后:

 $obj->doSomething(); 

由于它返回的是同一个对象,或者说是同一个对象的引用 ,所以你可以继续调用同一个类的方法来返回值,如下所示:

 $obj->doSomething()->doSomethingElse(); 

就是这样,真的。 两件重要的事情:

  1. 正如你注意到的,它只是PHP 5。 它在PHP 4中不能正常工作,因为它通过值返回对象,这意味着你在一个对象的不同副本上调用方法,这会破坏你的代码。

  2. 同样,你需要返回可链式方法中的对象:

     public function doSomething() { // Do stuff return $this; } public function doSomethingElse() { // Do more stuff return $this; } 

方法链接意味着您可以链接方法调用:

 $object->method1()->method2()->method3() 

这意味着method1()需要返回一个对象,method2()被赋予了method1()的结果。 Method2()然后将返回值传递给method3()。

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

试试这个代码:

 <?php class DBManager { private $selectables = array(); private $table; private $whereClause; private $limit; public function select() { $this->selectables = func_get_args(); return $this; } public function from($table) { $this->table = $table; return $this; } public function where($where) { $this->whereClause = $where; return $this; } public function limit($limit) { $this->limit = $limit; return $this; } public function result() { $query[] = "SELECT"; // if the selectables array is empty, select all if (empty($this->selectables)) { $query[] = "*"; } // else select according to selectables else { $query[] = join(', ', $this->selectables); } $query[] = "FROM"; $query[] = $this->table; if (!empty($this->whereClause)) { $query[] = "WHERE"; $query[] = $this->whereClause; } if (!empty($this->limit)) { $query[] = "LIMIT"; $query[] = $this->limit; } return join(' ', $query); } } // Now to use the class and see how METHOD CHAINING works // let us instantiate the class DBManager $testOne = new DBManager(); $testOne->select()->from('users'); echo $testOne->result(); // OR echo $testOne->select()->from('users')->result(); // both displays: 'SELECT * FROM users' $testTwo = new DBManager(); $testTwo->select()->from('posts')->where('id > 200')->limit(10); echo $testTwo->result(); // this displays: 'SELECT * FROM posts WHERE id > 200 LIMIT 10' $testThree = new DBManager(); $testThree->select( 'firstname', 'email', 'country', 'city' )->from('users')->where('id = 2399'); echo $testThree->result(); // this will display: // 'SELECT firstname, email, country, city FROM users WHERE id = 2399' ?> 

有49行代码可以让你像这样在数组上链接方法:

 $fruits = new Arr(array("lemon", "orange", "banana", "apple")); $fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key) { echo $key.': '.$value."\r\n"; }); 

看到这篇文章向您展示了如何链接所有PHP的七十个array_函数。

http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html

静态方法链接的另一种方法:

 class Maker { private static $result = null; private static $delimiter = '.'; private static $data = []; public static function words($words) { if( !empty($words) && count($words) ) { foreach ($words as $w) { self::$data[] = $w; } } return new static; } public static function concate($delimiter) { self::$delimiter = $delimiter; foreach (self::$data as $d) { self::$result .= $d.$delimiter; } return new static; } public static function get() { return rtrim(self::$result, self::$delimiter); } } 

调用

 echo Maker::words(['foo', 'bob', 'bar'])->concate('-')->get(); echo "<br />"; echo Maker::words(['foo', 'bob', 'bar'])->concate('>')->get(); 
 class JobModel implements JobInterface{ protected $job; public function __construct(Model $job){ $this->job = $job; } public function find($id){ return $this->job->find($id); } public function with($data=[]){ $this->job = $this->job->with($params); return $this; } } class JobController{ protected $job; public function __construct(JobModel $job){ $this->job = $job; } public function index(){ // chaining must be in order $this->job->with(['data'])->find(1); } } 
    Interesting Posts