当前位置:Gxlcms > PHP教程 > PHP中Closure类详解

PHP中Closure类详解

时间:2021-07-01 10:21:17 帮助过:57人阅读

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

  1. Closure {
  2. __construct ( void )
  3. public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
  4. public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])
  5. }

方法说明:

Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

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

下面将介绍Closure::bindClosure::bindTo

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

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

closure表示需要绑定的闭包对象。
newthis表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。
newscope表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是 'static', 表示不改变。

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

例子说明:

  1. <?php
  2. /**
  3. * 复制一个闭包,绑定指定的$this对象和类作用域。
  4. *
  5. * @author 疯狂老司机
  6. */
  7. class Animal {
  8. private static $cat = "cat";
  9. private $dog = "dog";
  10. public $pig = "pig";
  11. }
  12. /*
  13. * 获取Animal类静态私有成员属性
  14. */
  15. $cat = static function() {
  16. return Animal::$cat;
  17. };
  18. /*
  19. * 获取Animal实例私有成员属性
  20. */
  21. $dog = function() {
  22. return $this->dog;
  23. };
  24. /*
  25. * 获取Animal实例公有成员属性
  26. */
  27. $pig = function() {
  28. return $this->pig;
  29. };
  30. $bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
  31. $bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
  32. $bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
  33. echo $bindCat(),'<br>';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
  34. echo $bindDog(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
  35. echo $bindPig(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性
  36. ?>

输出:

cat
dog
pig

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

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

newthis表示绑定给闭包对象的一个对象,或者NULL来取消绑定。
newscope表示关联到闭包对象的类作用域,可以传入类名或类的示例,默认值是 'static', 表示不改变。

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

例子1:

  1. <?php
  2. function __autoload($class) {
  3. require_once "$class.php";
  4. }
  5. $template = new Template;
  6. $template->render(new Article, 'tpl.php');
  7. ?>

Template.php 模板类

  1. <?php
  2. /**
  3. * 模板类,用于渲染
输出 * * @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 信息类

  1. <?php
  2. /**
  3. * 文章信息类
  4. *
  5. * @author 疯狂老司机
  6. */
  7. class Article{
  8. private $title = "这是文章标题";
  9. private $content = "这是文章内容";
  10. }

tpl.php 模板文件

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  5. </head>
  6. <body>
  7. <h1><?php echo $this->title;?></h1>
  8. <p><?php echo $this->content;?></p>
  9. </body>
  10. </html>

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

输出:

这是文章标题

这是文章内容

例子2:

  1. <?php
  2. /**
  3. * 给类动态添加新方法
  4. *
  5. * @author 疯狂老司机
  6. */
  7. trait DynamicTrait {
  8. /**
  9. * 自动调用类中存在的方法
  10. */
  11. public function __call($name, $args) {
  12. if(is_callable($this->$name)){
  13. return call_user_func($this->$name, $args);
  14. }else{
  15. throw new \RuntimeException("Method {$name} does not exist");
  16. }
  17. }
  18. /**
  19. * 添加方法
  20. */
  21. public function __set($name, $value) {
  22. $this->$name = is_callable($value)?
  23. $value->bindTo($this, $this):
  24. $value;
  25. }
  26. }
  27. /**
  28. * 只带属性不带方法动物类
  29. *
  30. * @author 疯狂老司机
  31. */
  32. class Animal {
  33. use DynamicTrait;
  34. private $dog = 'dog';
  35. }
  36. $animal = new Animal;
  37. // 往动物类实例中添加一个方法获取实例的私有属性$dog
  38. $animal->getdog = function() {
  39. return $this->dog;
  40. };
  41. echo $animal->getdog();
  42. ?>

输出:

dog

例子3:

  1. <?php
  2. /**
  3. * 一个基本的购物车,包括一些已经添加的商品和每种商品的数量
  4. *
  5. * @author 疯狂老司机
  6. */
  7. class Cart {
  8. // 定义商品价格
  9. const PRICE_BUTTER = 1.00;
  10. const PRICE_MILK = 3.33;
  11. const PRICE_EGGS = 8.88;
  12. protected $products = array();
  13. /**
  14. * 添加商品和数量
  15. *
  16. * @access public
  17. * @param string 商品名称
  18. * @param string 商品数量
  19. */
  20. public function add($item, $quantity) {
  21. $this->products[$item] = $quantity;
  22. }
  23. /**
  24. * 获取单项商品数量
  25. *
  26. * @access public
  27. * @param string 商品名称
  28. */
  29. public function getQuantity($item) {
  30. return isset($this->products[$item]) ? $this->products[$item] : FALSE;
  31. }
  32. /**
  33. * 获取总价
  34. *
  35. * @access public
  36. * @param string 税率
  37. */
  38. public function getTotal($tax) {
  39. $total = 0.00;
  40. $callback = function ($quantity, $item) use ($tax, &$total) {
  41. $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($item));
  42. $total += ($pricePerItem * $quantity) * ($tax + 1.0);
  43. };
  44. array_walk($this->products, $callback);
  45. return round($total, 2);;
  46. }
  47. }
  48. $my_cart = new Cart;
  49. // 往购物车里添加商品及对应数量
  50. $my_cart->add('butter', 10);
  51. $my_cart->add('milk', 3);
  52. $my_cart->add('eggs', 12);
  53. // 打出出总价格,其中有 5% 的销售税.
  54. echo $my_cart->getTotal(0.05);
  55. ?>

输出:

132.88

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

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

介绍php中closure使用实例

php 中的closure用法实例详解

php 中closure的介绍

以上就是PHP中Closure类详解的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行