PHP 實現鏈式操作

1.應用場景

瞭解學習借鑑 php[框架中]實現鏈式操作實現原理

2.學習/操作

測試環境:

win10 64位 專業版

 

2.1 //適用於php 自帶的內置函數調用

比如:

在php中有很多字符串函數,例如要先過濾字符串收尾的空格,再求出其長度,一般的寫法是:
strlen(trim($str))
如果要實現類似js中的鏈式操作,比如像下面這樣應該怎麼寫?
$str->trim()->strlen()

1. 方式一 使用魔法函數__call結合call_user_func來實現

<?php
class StringHelper 
{
  private $value;
   
  public function __construct($value)
  {
    $this->value = $value;
  }
 
  public function __call($function, $args){
      //var_export($function); // trim
      //var_export($args); // array ( 0 => '0', )
      //exit;
    $this->value = call_user_func($function, $this->value, $args[0]); //這裏參數是根據 要調用函數[閉包]的參數而定 trim('str', '0');
    return $this;
  }
 
  function strlen() {
    return strlen($this->value);
  }
}

$str = " sd f 0";
$str = new StringHelper($str);
echo $str->trim('0')->strlen();  //處理字符串兩遍0的字符

輸出:

 

 

2. 方式二  使用魔法函數__call結合call_user_func_array來實現
class StringHelper 
{
  private $value;
   
  public function __construct($value)
  {
    $this->value = $value;
  }
 
  public function __call($function, $args){
    //  var_export($args); // array ( 0 => '0', )
    array_unshift($args, $this->value);
    // var_export($args); // array ( 0 => ' sd f 0', 1 => '0', )
    // exit;
    $this->value = call_user_func_array($function, $args); //依然是按照回調函數的參數順序而定的, 只不過第二個參數是數組形式
    return $this;
  }
 
 public function strlen() {
    return strlen($this->value);
  }
}
 
$str = new StringHelper(" sd f 0");
echo $str->trim('0')->strlen();

輸出:

 

備註:

array_unshift() 函數用於向數組插入新元素。新數組的值將被插入到數組的開頭。

call_user_func()和call_user_func_array都是動態調用函數的方法,區別在於參數的傳遞方式不同。

 

3.方式三  不使用魔法函數__call來實現

 

只需要修改_call()爲trim()函數即可:

 

class StringHelper 
{
    private $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function trim($t)
    {
        $this->value = trim($this->value, $t);
        return $this;
    }

    public function strlen() {
        return strlen($this->value);
    }
}

$str = " sd f 0";
$str = new StringHelper($str);
echo $str->trim('0')->strlen();

輸出:

 

擴展:  [方式三 擴展爲可以 不分順序調用]
class StringHelper 
{
    private $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function __toString() {
        return (string)$this->value; //必須返回string類型
    }

    public function trim($t)
    {
        $this->value = trim($this->value, $t);
        return $this;
    }

    public function strlen() {
        $this->value = strlen($this->value);
        //echo $this->value; //7
        //exit;
        //var_export($this); //StringHelper::__set_state(array( 'value' => 7, ))
        //exit;
        return $this;
    }
}

$str = " sd f 0";
$str = new StringHelper($str);
echo $str->trim('0')->strlen();  //輸出 6
echo "<br>";
echo $str->strlen()->trim('0'); // 輸出 1

輸出:

 

 

2.2 自定義函數/方法的鏈式調用[框架中使用]
TBD

 

 

 

 

 

 

 

 

後續補充

...

3.問題/補充

TBD

4.參考

https://www.jb51.net/article/103836.htmhttps://www.jb51.net/article/103836.htm  //PHP三種方式實現鏈式操作詳解

https://www.php.cn/php-weizijiaocheng-395865.html  //PHP 中__call()的使用方法

https://www.php.cn/php-weizijiaocheng-390011.html  //PHP中__call()和__callStatic()使用方法

https://www.php.net/manual/zh/function.call-user-func.php  //call_user_func

https://www.php.net/manual/zh/function.call-user-func-array.php  //call_user_func_array

https://www.php.net/manual/zh/language.oop5.magic.php  //魔術方法

https://www.php.net/manual/zh/language.oop5.overloading.php#object.call  // __call 與 __callStatic方法重載

https://www.php.net/manual/zh/language.oop5.magic.php#object.tostring  //__toString

https://www.cnblogs.com/-simon/p/5875128.html  //PHP實現鏈式操作的原理

https://www.cnblogs.com/yangtoude/p/php-simple-chain-operation-implementation.html  //用php實現一個簡單的鏈式操作

 

<<PHP核心技術與最佳實踐>> -- Page 9  //之前讀, 沒看明白, 現在倒是看懂了些. 有些書還是要多讀, 多實踐

後續補充

...

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章