用php实现一个简单的链式操作
2018-06-22 05:01:55来源:未知 阅读 ()
最近在读《php核心技术与最佳实践》这本书,书中第一章提到用__call()方法可以实现一个简单的字符串链式操作,比如,下面这个过滤字符串然后再求长度的操作,一般要这么写:
strlen(trim($str));
那么能否实现下面这种写法呢?
$str->trim()->strlen();
下面就来试下。
链式操作,说白了其实就是链式的调用对象的方法。既然要实现字符串的链式操作,那么就要实现一个字符串类,然后对这个类的对象进行调用操作。我对字符串类的期望如下:(1)当我创建对象时,我可以将字符串赋值给对象的属性,并且可以访问这个属性读取值;(2)我可以调用trim() 和strlen()方法;(3)我还可以这么调用方法$str->trim()->strlen()。
上面的第(1)条,是一个字符串类的基本要求。先把这个实现了:
1 class String 2 { 3 public $value; 4 5 public function __construct($str=null) 6 { 7 $this->value = $str; 8 } 9 }
可以试下:
1 $str = new String('01389'); 2 echo $str->value;
然后再看第2条,先把$str->trim()实现了,参考书中的思路:触发__call方法然后执行call_user_func。代码如下:
1 class String 2 { 3 public $value; 4 5 public function __construct($str=null) 6 { 7 $this->value = $str; 8 } 9 10 public function __call($name, $args) 11 { 12 $this->value = call_user_func($name, $this->value, $args[0]); 13 return $this; 14 } 15 }
测试下:
1 $str = new String('01389'); 2 echo $str->trim('0')->value;
结果如下:
上面需要注意的是第12行: $this->value = call_user_func($name, $this->value, $args[0]); $name是回调函数的名字(这里也就是trim),后面两个是回调函数(trim)的参数,参数的顺序不要弄颠倒了。$args是数组,也需要注意下。
第2条中还要实现strlen(),这时上面代码中的第13行就很关键了: return $this; 它的作用就是,在第12行调用trim()处理完字符串后重新value属性赋值,然后返回当前对象的引用,这样对象内的其他方法就可以对属性value进行连续操作了,也就实现了链式操作。$str->strlen()实现如下:
1 class String 2 { 3 public $value; 4 5 public function __construct($str=null) 6 { 7 $this->value = $str; 8 } 9 10 public function __call($name, $args) 11 { 12 $this->value = call_user_func($name, $this->value, $args[0]); 13 return $this; 14 } 15 16 public function strlen() 17 { 18 return strlen($this->value); 19 } 20 }
测试下:
1 $str = new String('01389'); 2 echo $str->strlen();
结果:
链式操作:
echo $str->trim('0')->strlen();
结果:
到这里,这篇文章本该就结束了。但是,我想了下,其实不用__call()方法,也是可以实现链式操作的。下面是不用__call()的实现:
1 class String 2 { 3 public $value; 4 5 public function __construct($str=null) 6 { 7 $this->value = $str; 8 } 9 10 public function trim($t) 11 { 12 $this->value = trim($this->value, $t); 13 return $this; 14 } 15 16 public function strlen() 17 { 18 return strlen($this->value); 19 } 20 }
链式操作的关键是在做完操作后要return $this。
另外,本文受到园子里这篇文章的启发,用call_user_func_array()替换了call_user_func()实现,将__call()方法修改如下。
1 public function __call($name, $args) 2 { 3 array_unshift($args, $this->value); 4 $this->value = call_user_func_array($name, $args); 5 return $this; 6 }
与上面的__call()方法效果是相同的,这样代码似乎比之前的实现要优雅些。
总结:
__call()在对象调用一个不可访问的方法时会被触发,所以可以实现类的动态方法的创建,实现php的方法重载功能,但它其实是一个语法糖(__construct()方法也是)。
那么如果没有__call()等语法糖,能否实现动态方法的创建和链式操作呢?我想会涉及到以下几个方面的问题:类方法是否存在和可以调用,这个可以用method_exists、is_callable、get_class_methods等方法来实现,另外,就是在创建对象时给属性赋值(初始化),这个语法糖确实方便,不过不是必需的。等有时间再研究下吧。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:以前一些问题解决记录
- PHP写UltraEdit插件脚本实现方法 2020-03-29
- php 带逗号千位符数字的处理方法 2020-03-28
- PHP三元运算符的结合性介绍 2020-03-28
- PHP静态延迟绑定和普通静态效率的对比 2020-03-28
- 基于php流程控制语句和循环控制语句 2020-03-28
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash