php鏈式呼叫

y0umer發表於2012-07-16

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


相關文章