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" 
 *  } 
 *  
 *  
 * 
 * 
 **/ 

原文地址:https://www.cnblogs.com/y0umer/p/3838872.html