ITPub博客

首页 > 应用开发 > IT综合 > 如何在PHP中实现链式方法调用

如何在PHP中实现链式方法调用

原创 IT综合 作者:bh267940 时间:2021-03-01 12:01:15 0 删除 编辑

  写程序的人都喜欢偷懒,希望少打几行代码,并且让代码看起来很酷。

  所以很多人写程序都会选择三元运算取代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博客 ” ,链接:https://blog.itpub.net/69976869/viewspace-2760200/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 最优排序算法
请登录后发表评论 登录
全部评论

注册时间:2020-07-13

  • 博文量
    12
  • 访问量
    27139