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  //之前读, 没看明白, 现在倒是看懂了些. 有些书还是要多读, 多实践

后续补充

...

发布了456 篇原创文章 · 获赞 44 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/william_n/article/details/104989326