PHP Closure 类是用于代表匿名函数的类,匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,Closure类摘要如下:

Closure { __construct ( void ) public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ]) public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])}

方法说明:

Closure::__construct — 用于禁止实例化的构造函数

Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。

Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

除了此处列出的方法,还有一个 __invoke 方法。这是为了与其他实现了 __invoke()魔术方法 的对象保持一致性,但调用闭包对象的过程与它无关。

下面将介绍Closure::bind和Closure::bindTo。

Closure::bind是Closure::bindTo的静态版本,其说明如下:

public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])

closure表示需要绑定的闭包对象。

newthis表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。

newscope表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是 ‘static’, 表示不改变。

该方法成功时返回一个新的 Closure 对象,失败时返回FALSE。

例子说明:

<?php /** * 复制一个闭包,绑定指定的$this对象和类作用域。 * * @author 疯狂老司机 */class Animal { private static $cat = "cat"; private $dog = "dog"; public $pig = "pig";} /* * 获取Animal类静态私有成员属性 */$cat = static function() { return Animal::$cat;}; /* * 获取Animal实例私有成员属性 */$dog = function() { return $this->dog;}; /* * 获取Animal实例公有成员属性 */$pig = function() { return $this->pig;}; $bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域echo $bindCat(),'
';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性echo $bindDog(),'
';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性echo $bindPig(),'
';// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性?>

输出:

cat

dog

pig

Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域,其说明如下:

public Closure Closure::bindTo (object $newthis [, mixed $newscope = 'static' ])

newthis表示绑定给闭包对象的一个对象,或者NULL来取消绑定。

newscope表示关联到闭包对象的类作用域,可以传入类名或类的示例,默认值是 ‘static’, 表示不改变。

该方法创建并返回一个闭包对象,它与当前对象绑定了同样变量,但可以绑定不同的对象,也可以绑定新的类作用域。绑定的对象决定了返回的闭包对象中的$this的取值,类作用域决定返回的闭包对象能够调用哪些方法,也就是说,此时$this可以调用的方法,与newscope类作用域相同。

例子1:

<?phpfunction __autoload($class) { require_once "$class.php";} $template = new Template;$template->render(new Article, 'tpl.php');?>

Template.php 模板类

<?php /** * 模板类,用于渲染输出 * * @author 疯狂老司机 */class Template{ /** * 渲染方法 * * @access public * @param obj 信息类 * @param string 模板文件名 */ public function render($context, $tpl){ $closure = function($tpl){ ob_start(); include $tpl; return ob_end_flush(); }; $closure = $closure->bindTo($context, $context); $closure($tpl); } }

Article.php 信息类

tpl.php 模板文件

<?php echo $this->title;?>

<?php echo $this->content;?>

运行时确保以上文件位于同级目录。

输出:

这是文章标题

这是文章内容例子2:

<?php /** * 给类动态添加新方法 * * @author 疯狂老司机 */trait DynamicTrait { /** * 自动调用类中存在的方法 */ public function __call($name, $args) { if(is_callable($this->$name)){ return call_user_func($this->$name, $args); }else{ throw new \RuntimeException("Method {$name} does not exist"); } } /** * 添加方法 */ public function __set($name, $value) { $this->$name = is_callable($value)? $value->bindTo($this, $this): $value; }} /** * 只带属性不带方法动物类 * * @author 疯狂老司机 */class Animal { use DynamicTrait; private $dog = 'dog';} $animal = new Animal; // 往动物类实例中添加一个方法获取实例的私有属性$dog$animal->getdog = function() { return $this->dog;}; echo $animal->getdog(); ?>

输出:

dog

例子3:

<?php /** * 一个基本的购物车,包括一些已经添加的商品和每种商品的数量 * * @author 疯狂老司机 */class Cart { // 定义商品价格 const PRICE_BUTTER = 1.00; const PRICE_MILK = 3.33; const PRICE_EGGS = 8.88; protected $products = array(); /** * 添加商品和数量 * * @access public * @param string 商品名称 * @param string 商品数量 */ public function add($item, $quantity) { $this->products[$item] = $quantity; } /** * 获取单项商品数量 * * @access public * @param string 商品名称 */ public function getQuantity($item) { return isset($this->products[$item]) ? $this->products[$item] : FALSE; } /** * 获取总价 * * @access public * @param string 税率 */ public function getTotal($tax) { $total = 0.00; $callback = function ($quantity, $item) use ($tax, &$total) { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($item)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; array_walk($this->products, $callback); return round($total, 2);; }} $my_cart = new Cart; // 往购物车里添加商品及对应数量$my_cart->add('butter', 10);$my_cart->add('milk', 3);$my_cart->add('eggs', 12); // 打出出总价格,其中有 5% 的销售税.echo $my_cart->getTotal(0.05); ?>

输出:

132.88

补充说明:闭包可以使用USE关键连接外部变量。

总结:合理使用闭包能使代码更加简洁和精炼。

https://blog.csdn.net/wuxing26jiayou/article/details/51067190

php closure invoke,PHP Closure类详解相关推荐

  1. php closure 类,PHP中Closure类详解

    本文主要和大家分享PHP中Closure类详解,PHP Closure 类是用于代表匿名函数的类,匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,Closure类摘要如下:Closure ...

  2. JDBC从入门到熟练使用——功能类详解、增删改查(CRUD)、sql注入、事务、连接池

    一.JDBC入门 1.jdbc的概念 JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问 ...

  3. OpenCV Mat类详解和用法(官网原文)

    参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...

  4. 转载:c+string类详解

    C++ string 类详解 </h1><div class="clear"></div><div class="postBod ...

  5. JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  6. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  7. Android复习14【高级编程:推荐网址、抠图片上的某一角下来、Bitmap引起的OOM问题、三个绘图工具类详解、画线条、Canvas API详解(平移、旋转、缩放、倾斜)、矩阵详解】

    目   录 推荐网址 抠图片上的某一角下来 8.2.2 Bitmap引起的OOM问题 8.3.1 三个绘图工具类详解 画线条 8.3.16 Canvas API详解(Part 1) 1.transla ...

  8. Java中的Runtime类详解

    Java中的Runtime类详解 1.类注释 /**Every Java application has a single instance of class Runtime that allows ...

  9. [NewLife.XCode]实体类详解

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  10. basicdatasourcefactory mysql_Java基础-DBCP连接池(BasicDataSource类)详解

    Java基础-DBCP连接池(BasicDataSource类)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际开发中"获得连接"或"释放资源 ...

最新文章

  1. 2.4操作系统之死锁详解(预防、避免、检测、解除)+思维导图
  2. python之selenium调用js(execute_script)
  3. rapidjson 嵌套json_[整理][RapidJson用法2]C++之RapidJson创建嵌套数组json | 勤奋的小青蛙...
  4. Android 4 学习(20):ActionBar
  5. HTML5中微数据在搜索引擎中的使用举例
  6. java日志文件log4j.properties配置详解
  7. java 串口判断报文完整_如何判断串口接收完成一帧数据
  8. PCB设计之:必知的PCB设计八大误区
  9. MySQL数据库入门(超详细,多图解)
  10. 台达服务器AB和B2系列区别,台达伺服各系列区别
  11. COMSOL光纤建模、光子带隙分析等
  12. 疫情下技术人的宅家指南
  13. linux root定时脚本,shell之定时周期性执行脚本的方法示例
  14. JavaScript数据类型 1
  15. 地铁WIFI可以用来挣钱,可挣钱却注定很难
  16. 练习-Java类和对象之对象组合之求圆锥体表面积
  17. 微软研发类实习生面试
  18. echart旭日图_echarts(10):旭日图
  19. 操作系统---linux
  20. N2N(docker方式安装)实现远程访问家里群晖

热门文章

  1. 由于CRS磁盘dismount造成的CRS进程无法启动问题
  2. mysql在表的某一位置增加一列、删除一列、修改列名
  3. eNSP中玩转Python自动化——解锁网工新姿势
  4. leetcode-139-单词拆分
  5. 路由器配置——OSPF协议(2)
  6. unity3d的执行顺序
  7. 优化:更优雅的异步代码?
  8. OpenStack概念架构简述
  9. Json字符串和Json对象的简单总结
  10. [转]MSXML版本历史