您好,欢迎访问一九零五行业门户网

PHP中Closure类详解

本文主要和大家分享php中closure类详解,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(),'<br>';// 根据绑定规则,允许闭包通过作用域限定操作符获取animal类静态私有成员属性 echo $binddog(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象(animal实例对象)获取animal实例私有成员属性 echo $bindpig(),'<br>';// 根据绑定规则,允许闭包通过绑定的$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:
<?php function __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 信息类
<?php /** * 文章信息类 * * @author 疯狂老司机 */ class article{ private $title = "这是文章标题"; private $content = "这是文章内容"; }
tpl.php 模板文件
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> </head> <body> <h1><?php echo $this->title;?></h1> <p><?php echo $this->content;?></p> </body> </html>
运行时确保以上文件位于同级目录。
输出:
这是文章标题这是文章内容
例子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关键连接外部变量。
总结:合理使用闭包能使代码更加简洁和精炼。
相关推荐:
介绍php中closure使用实例
php 中的closure用法实例详解
php 中closure的介绍
以上就是php中closure类详解的详细内容。
其它类似信息

推荐信息