一.依据闭包实现一个容器

class Di
{
private $factory; public function set($id, $value)
{
$this->factory[$id] = $value;
} public function get($id)
{
$val = $this->factory[$id];
return $val();//如果不加括号,仅仅返回的是闭包类,并不是User实例
}
} class User
{
private $username; public function __construct($username = '')
{
$this->username = $username;
} public function getUserName()
{
return $this->username;
}
} $di = new Di(); // 在此使用了闭包,所以实际上并不会实例化User类,只有在后面get的时候才会实例化
$di->set('a', function(){
return new User('张三');
}); var_dump($di->get('a')->getUserName());

  

二.使用闭包作为回调

class Cart
{
CONST PRICE_BUTTER = 1.0;
CONST PRICE_MILK = 5.05; protected $products = []; public function add($product, $quantity)
{
$this->products[$product] = $quantity;
} public function getQuantity($product)
{
return isset($this->products[$product]) ? $this->products[$product]: false;
} public function getTotal($tax)
{
$total = 0.00;
$callback = function($quantity, $product) use ($tax, &$total) {
$priceItem = constant(__CLASS__ . '::PRICE_' . strtoupper($product));
$total += ($priceItem * $quantity) * ($tax + 1.0);
}; array_walk($this->products, $callback);
return round($total, 2);
}
} $cart = new Cart();
$cart->add('butter', 1);
$cart->add('milk', 5); echo $cart->getTotal(0.05);

  

三.使用闭包函数调用类中方法

class Grid
{
protected $builder;
protected $attribute; public function __construct(Closure $builler)
{
$this->builder = $builler;
} public function addColumn($name, $value)
{
$this->attribute[$name] = $value;
return $this;
} public function build()
{
// 这儿回调闭包函数,参数为this
call_user_func($this->builder, $this);
} public function __toString()
{
$this->build(); $str = '';
$call = function($val, $key) use(&$str) {
$str .= "$key=>$val;";
};
array_walk($this->attribute, $call); return $str;
}
} $grid = new Grid(
// 传入闭包函数,带参数
function($grid) {
$grid->addColumn('key1', 'val1');
$grid->addColumn('key2', 'val2');
}
); echo $grid;

  

闭包在对象中的一个典型使用场景就是留出一个方法给调用者,让调用者自主决定或组装数据.
如下例:让调用者决定如何组装或显示info.

class CalledClass {
private $name;
private $age;
private $info; public function __construct($name, $age, Closure $callable)
{
$this->name = $name;
$this->age = $age;
call_user_func($callable, $this);
// 这相当于
// $callable($this);
} public function setInfo($info)
{
$this->info = $info;
} public function getInfo()
{
echo $this->info;
} /**
* @return mixed
*/
public function getName()
{
return $this->name;
} /**
* @return mixed
*/
public function getAge()
{
return $this->age;
} } $c = new CalledClass('php', 10, function (CalledClass $c) {
echo $c->getAge() . $c->getName();
$c->setInfo($c->getAge() . $c->getName());
}); echo $c->getInfo();

  

php闭包使用例子的更多相关文章

  1. javascript闭包学习例子

    javascript中的闭包个很让人头疼的概念.总结一下 闭包是指有权访问一个函数作用域中的变量的函数.创建闭包最常见的方式,是在一个函数内部创建另一个函数,用return返回出去. 使用闭包可能造成 ...

  2. javascript 闭包理解例子

    function Jquery(){ this.name = 'ysr'; this.sex = 'man'; return { x: this, age : 26 } } var b = new J ...

  3. JavaScript 闭包的例子

    例子出自<<JavaScript权威指南>>, 加上个人的理解和总结, 欢迎交流! /********************************************* ...

  4. python闭包小例子

    ------------------ 首先根据实例, 体会一下闭包的效果 ------------------ 定义闭包: def foo(x): a = [0] def bar(y): a[0] = ...

  5. 一段关于python 闭包的例子

    >>> def counter(a=0): ... count = a ... def incr(): ... b = 1 + count ... return b ... retu ...

  6. js闭包原理与例子[转]

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.闭包原理: 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域 ...

  7. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  8. 【javascript】作用域和闭包浅析

    作用域 分全局作用域和局部作用域 全局作用域:函数外部定义的变量,可以被整个program的各成员参照利用. 局部作用域:函数内部定义的变量,仅供该函数的各成员参照利用. var val=1; //全 ...

  9. C# 闭包

    1. 首先要说明的是, delegate 被编译器 编译成一个class, 所以才能传来传去(具体参考 <CLR via C#>第四版), 所以 Action.Func也是如此 2. 在C ...

随机推荐

  1. [ CodeVS冲杯之路 ] P1294

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1294/ 随手一打就是这么漂亮的全排列,想当年我初一还是初二的时候,调了1个多小时才写出来(蒟蒻一枚) 直接DFS每次枚 ...

  2. Winform 在DataGrid中签入Combo

    背景 最近看了Winform在DataGrid中怎么嵌入Combo,想到平时项目中写到的一些临时小工具,经常用配置参数,有些配置是简单的地址或文本,有些则是类似1代表SQL,2代表Oracle等.于是 ...

  3. source insight setting

    adjust source code font size Options -> File Type Options -> Screen Font -> Size adjust dis ...

  4. python的优化机制与垃圾回收与gc模块

    python属于动态语言,我们可以随意的创建和销毁变量,如果频繁的创建和销毁则会浪费cpu,那么python内部是如何优化的呢? python和其他很多高级语言一样,都自带垃圾回收机制,不用我们去维护 ...

  5. C++内联汇编,输出人物名字

    DWORD PeopleBase =0x9CD674;//天龙人物基址 //获取人物名称 char * CData::GetPeopleName() {     char * name="& ...

  6. 部署站点支持Https访问的方法

    1.申请公钥和私钥,放到服务器 2.编辑default配置文件 改为 加上证书路径 ps:泛域名支持admin.xxx.com.demo.xxx.com等等,而免费的Let's Encrypt仅支持w ...

  7. HDU 6301.Distinct Values-贪心、构造字典序最小的数列 (2018 Multi-University Training Contest 1 1004)

    HDU6301.Distinct Values 这个题就是给你区间要求区间内的数都不相同,然后要求是字典序最小,直接贪心走一遍,但是自己写的时候,思路没有错,初始化写挫了... 将区间按左端点小的排序 ...

  8. Codeforces Gym100952 C. Palindrome Again !!-回文字符串 (2015 HIAST Collegiate Programming Contest)

      C. Palindrome Again !!   time limit per test 1 second memory limit per test 64 megabytes input sta ...

  9. 谷歌浏览器cookies管理插件:EditThisCookie

    目前大多数网站的登录程序或者是其他保存用户信息到本地浏览器的方式都是使用cookies的方式,而cookies虽然可以为用户的一些操作带来便捷,比如可以记住用户的密码或者用户的选择历史,在下一次操作的 ...

  10. [POJ 2373][BZOJ 1986] Dividing the Path

    Link: POJ 2373 传送门 Solution: 一开始想错方向的一道简单$dp$,不应该啊…… 我一开始的想法是以$cows' ranges$的节点为状态来$dp$ 但明显一个灌溉的区间的两 ...