如何在PHP中實現鏈式方法呼叫

bh267940發表於2021-03-01

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

  所以很多人寫程式都會選擇三元運算取代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 -

  */

  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"

  *  }

  *

  *

  *

  *

  **/

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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69976869/viewspace-2760200/,如需轉載,請註明出處,否則將追究法律責任。

相關文章