php链式调用
转自默默 http://bbs.phpchina.com/thread-237323-1-1.html
写程序的人都喜欢偷懒,希望少打几行代码,并且让代码看起来很酷。
所以很多人写程序都会选择三元运算取代if..else...。而用过JS的人应该都见识过js中的链式方法。
如 somevars.func().func2().func3()...funcN();
这样的写法使得代码更简练,并且作用关系一目了然。
那么在php中可以这么做么,显然也是可以的,但是php与js的差别是,在js中变量本身具有对象的性质,但是php的变量却不是。
所以解决方法就是让php的变量变成一个对象。
代码如下:
<?php error_reporting(E_ALL | E_STRICT); /** * PHP-OOP_VAR 让php的变量变成一个对象 * * * @version 0.0.1 * @author momodev * @website http://momodev.blog.51cto.com * @license GPL v3 - http://vork.us/go/mvz5 */ Abstract Class Base_OOP_VAR{ /** * 追溯数据,用来进行调试 * @var array */ private $_trace_data = array(); /** * 保存可用的方法列表 * @var array */ protected $_methods = array( ); /** * 数据本身 * @var null */ protected $data; /** * 初始化变量 * @param var * @return void */ public function __construct($data){ $this->data = $data; $this->_trace_data['__construct'] = $data; return $this->data; } /** * 魔术方法,当试图对对象进行打印如 echo 或print的时候,调用这个方法 * * 比如: * $a = new stdClass; * echo $a; * 等价于 echo $a->__toString(); * * @return $data */ public function __toString(){ if(is_int($this->data) || is_float($this->data)) $this->data = (string)$this->data; return $this->data; } /** * 魔术方法,当试图调用一个不存在的方法时,这个函数会接管这个请求 * * 比如 * $a= new stdClass; * $a->output(); * 等价于 * $a->__call("output"); * * @return object */ public function __call($name,$args){ $this->vaild_func($name); if(!$args) $args = $this->data; $this->data = call_user_func($name,$args); $this->_trace_data[$name] = $this->data; return $this; } /** * 检查方法是否是有效的 * @params string $name * @return void */ private function vaild_func($name){ if(!in_array($name,$this->_methods)){ throw new Exception("invaild method"); } } /** * 对数据进行追溯 * 比如 * $a = new String(" Hello World"); * $a->trim()->strlen(); * 在调用trim的时候,实际上把前后的空格给去掉了,所以数据是 * Hello World * 在调用strlen的时候 * 得到了一个字符串长度的值 * 追溯数据方便检查在哪个环节数据出现了问题 * * @return string */ public function trace(){ echo "<pre>"; var_dump($this->_trace_data); echo "</pre>"; } } /** * ex. 怎么来使用这个抽象类 * * 声明一个字符串对象 * class String extends Base_OOP_VAR{ * //添加可用的方法 * protected $_methods = array( * 'trim', * 'strlen', * 'gettype' * ); * * } * //使用这个对象 * $a = new String(" Hello world"); * echo $a->trim()->strlen()->gettype(); * $a->trace(); * //调试的数据类似这样 * array(4) { * //初始化时的数据 * ["__construct"]=> string(12) " Hello world" * //去除前后空格的数据 * ["trim"]=> string(11) "Hello world" * //代表字符串长度的数据 * ["strlen"]=> int(11) * //代表字符串类型的数据 * ["gettype"]=> string(7) "integer" * } * * * * **/