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

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. 【原创】Linux环境下的图形系统和AMD R600显卡编程(4)——AMD显卡显存管理机制

    显卡使用的内存分为两部分,一部分是显卡自带的显存称为VRAM内存,另外一部分是系统主存称为GTT内存(graphics translation table和后面的GART含义相同,都是指显卡的页表,G ...

  2. 数据库函数:sqlite3_exec() SQL语句

    函数:sqlite3_exec(),称为便捷函数,封装了好多任务. 函数声明: int  sqlite3_exec( sqlite   * , const  char * sql , sqlite_c ...

  3. shell 将字符串分割成数组

    代码:test.sh #!/bin/bash a="one,two,three,four" #要将$a分割开,可以这样: OLD_IFS="$IFS" IFS= ...

  4. FileReader&FileWriter

    FileReader public static void main(String[] args) { //创建文件对象指定要读取的文件路径 File file=new File("d:\\ ...

  5. 利用Excel导出sql语句

    在工作中遇到了需要用数据库的insert语句,本来是极其简单的事情,但是碰到了有n个(n很大)字段的表,写insert语句就是极其痛苦的事情了,即使只是复制粘贴也是很费力不讨好的一件事.正好手头有ex ...

  6. 使用 ElasticSearch Aggregations 进行统计分析

    https://blog.csdn.net/zxjiayou1314/article/details/53837719/

  7. AC日记——The Child and Sequence codeforces 250D

    D - The Child and Sequence 思路: 因为有区间取模操作所以没法用标记下传: 我们发现,当一个数小于要取模的值时就可以放弃: 凭借这个来减少更新线段树的次数: 来,上代码: # ...

  8. J.U.C并发框架源码阅读(九)LinkedBlockingQueue

    基于版本jdk1.7.0_80 java.util.concurrent.LinkedBlockingQueue 代码如下 /* * ORACLE PROPRIETARY/CONFIDENTIAL. ...

  9. PostgreSQL(EXCEPT,INTERSECT)

    except 可以查看表一对表二不一样的数据,有点像是对表一进行表一表二交集的反集的交集,好绕: intersect 可以查看表一和表二一样的数据,求交集: select t1.name,t1.age ...

  10. UVA 437 巴比伦塔 【DAG上DP/LIS变形】

    [链接]:https://cn.vjudge.net/problem/UVA-437 [题意]:给你n个立方体,让你以长宽为底,一个个搭起来(下面的立方体的长和宽必须大于上面的长和宽)求能得到的最长高 ...