寫程式的人都喜歡偷懶,希望少打幾行程式碼,並且讓程式碼看起來很酷。

所以很多人寫程式都會選擇三元運算取代if..else…。

而用過JS的人應該都見識過js中的鏈式方法。

如 somevars.func().func2().func3()…funcN();

這樣的寫法使得程式碼更簡練,並且作用關係一目瞭然。

那麼在php中可以這麼做麼,顯然也是可以的,但是php與js的差別是,在js中變數本身具有物件的性質,但是php的變數卻不是。

所以解決方法就是讓php的變數變成一個物件。

程式碼如下:


  1. <?php 
  2. error_reporting(E_ALL | E_STRICT); 
  3. /** 
  4.  * PHP-OOP_VAR 讓php的變數變成一個物件 
  5.  * 
  6.  * 
  7.  * @version 0.0.1 
  8.  * @author momodev 
  9.  * @website http://momodev.blog.51cto.com 
  10.  * @license GPL v3 - http://vork.us/go/mvz5 
  11.  */ 
  12. Abstract Class Base_OOP_VAR{ 
  13.  
  14.     /** 
  15.      * 追溯資料,用來進行除錯 
  16.      * @var array 
  17.      */ 
  18.     private $_trace_data = array(); 
  19.  
  20.     /** 
  21.      * 儲存可用的方法列表 
  22.      * @var array 
  23.      */ 
  24.     protected $_methods = array
  25.     ); 
  26.  
  27.     /** 
  28.      * 資料本身 
  29.      * @var null 
  30.      */ 
  31.     protected $data
  32.  
  33.     /** 
  34.      * 初始化變數 
  35.      * @param var 
  36.      * @return void 
  37.      */ 
  38.     public function __construct($data){ 
  39.         $this->data = $data
  40.         $this->_trace_data[`__construct`] = $data
  41.         return $this->data; 
  42.     } 
  43.  
  44.     /** 
  45.      * 魔術方法,當試圖對物件進行列印如 echo 或print的時候,呼叫這個方法 
  46.      *  
  47.      * 比如: 
  48.      * $a = new stdClass; 
  49.      * echo $a; 
  50.      * 等價於 echo $a->__toString(); 
  51.      *  
  52.      * @return $data 
  53.      */ 
  54.     public function __toString(){ 
  55.         if(is_int($this->data) || is_float($this->data)) 
  56.             $this->data = (string)$this->data; 
  57.         return $this->data; 
  58.     } 
  59.  
  60.     /** 
  61.      * 魔術方法,當試圖呼叫一個不存在的方法時,這個函式會接管這個請求 
  62.      *  
  63.      * 比如 
  64.      * $a= new stdClass; 
  65.      * $a->output(); 
  66.      * 等價於 
  67.      * $a->__call("output"); 
  68.      *  
  69.      * @return object 
  70.      */ 
  71.     public function __call($name,$args){ 
  72.         $this->vaild_func($name); 
  73.         if(!$args$args = $this->data; 
  74.         $this->data =  call_user_func($name,$args); 
  75.         $this->_trace_data[$name] = $this->data; 
  76.         return $this
  77.     } 
  78.  
  79.     /** 
  80.      * 檢查方法是否是有效的 
  81.      * @params string $name 
  82.      * @return void 
  83.      */ 
  84.     private function vaild_func($name){ 
  85.         if(!in_array($name,$this->_methods)){ 
  86.             throw new Exception("invaild method"); 
  87.         } 
  88.     } 
  89.  
  90.     /** 
  91.      * 對資料進行追溯 
  92.      * 比如 
  93.      * $a = new String(" Hello World"); 
  94.      * $a->trim()->strlen(); 
  95.      * 在呼叫trim的時候,實際上把前後的空格給去掉了,所以資料是 
  96.      * Hello World 
  97.      * 在呼叫strlen的時候 
  98.      * 得到了一個字串長度的值 
  99.      * 追溯資料方便檢查在哪個環節資料出現了問題 
  100.      *  
  101.      * @return string 
  102.      */ 
  103.     public function trace(){ 
  104.         echo "<pre>"
  105.         var_dump($this->_trace_data); 
  106.         echo "</pre>"
  107.     } 
  108.  
  109.  
  110. /** 
  111.  * ex. 怎麼來使用這個抽象類 
  112.  * 
  113.  * 宣告一個字串物件 
  114.  * class String extends Base_OOP_VAR{ 
  115.  *  //新增可用的方法 
  116.  *  protected $_methods = array( 
  117.  *      `trim`, 
  118.  *      `strlen`, 
  119.  *      `gettype` 
  120.  *  ); 
  121.  * 
  122.  * } 
  123.  * //使用這個物件 
  124.  * $a = new String(" Hello world"); 
  125.  * echo $a->trim()->strlen()->gettype(); 
  126.  * $a->trace(); 
  127.  * //除錯的資料類似這樣 
  128.  * array(4) {  
  129.  *      //初始化時的資料 
  130.  *      ["__construct"]=> string(12) " Hello world" 
  131.  *      //去除前後空格的資料  
  132.  *      ["trim"]=> string(11) "Hello world" 
  133.  *      //代表字串長度的資料  
  134.  *      ["strlen"]=> int(11)  
  135.  *      //代表字串型別的資料 
  136.  *      ["gettype"]=> string(7) "integer" 
  137.  *  } 
  138.  *  
  139.  *  
  140.  * 
  141.  * 
  142.  **/ 

同時我已經把這個檔案放在了github上,歡迎童鞋們fork

https://github.com/momodev/PHP-OOP_VAR