php闭包使用例子
一.依据闭包实现一个容器
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闭包使用例子的更多相关文章
- javascript闭包学习例子
javascript中的闭包个很让人头疼的概念.总结一下 闭包是指有权访问一个函数作用域中的变量的函数.创建闭包最常见的方式,是在一个函数内部创建另一个函数,用return返回出去. 使用闭包可能造成 ...
- javascript 闭包理解例子
function Jquery(){ this.name = 'ysr'; this.sex = 'man'; return { x: this, age : 26 } } var b = new J ...
- JavaScript 闭包的例子
例子出自<<JavaScript权威指南>>, 加上个人的理解和总结, 欢迎交流! /********************************************* ...
- python闭包小例子
------------------ 首先根据实例, 体会一下闭包的效果 ------------------ 定义闭包: def foo(x): a = [0] def bar(y): a[0] = ...
- 一段关于python 闭包的例子
>>> def counter(a=0): ... count = a ... def incr(): ... b = 1 + count ... return b ... retu ...
- js闭包原理与例子[转]
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.闭包原理: 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域 ...
- 让你分分钟学会Javascript中的闭包
Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...
- 【javascript】作用域和闭包浅析
作用域 分全局作用域和局部作用域 全局作用域:函数外部定义的变量,可以被整个program的各成员参照利用. 局部作用域:函数内部定义的变量,仅供该函数的各成员参照利用. var val=1; //全 ...
- C# 闭包
1. 首先要说明的是, delegate 被编译器 编译成一个class, 所以才能传来传去(具体参考 <CLR via C#>第四版), 所以 Action.Func也是如此 2. 在C ...
随机推荐
- table 实现 九宫格布局
九宫格布局 最近遇到一个题目,是实现一个九宫格布局的.实现的效果大概是下图这种这样子的: (鼠标悬浮的时候,九宫格的边框颜色是改变的.) 首先想到的是直接使用<table>进行布局,原因很 ...
- mlock家族:锁定物理内存【转】
转自:http://blog.csdn.net/fjt19900921/article/details/8074541 锁住内存是为了防止这段内存被操作系统swap掉.并且由于此操作风险高,仅超级用户 ...
- cannot load shared object file undefined symbol
cannot load shared object file undefined symbol 场景: 共享库里引用了主程序一个符号,结构编译的时候没问题,运行时用 dlopen 打开共享库报上述错误 ...
- android.useDeprecatedNdk=true
android.useDeprecatedNdk=true ndk{ moduleName "aa" abiFilter "armeabi-v7a" }
- 自定义validate的效验规则 检验用户名是否存在
<script type="text/javascript"> //自定义效验规则 $.validator.addMethod( //规则名称 "checkU ...
- poj 1106(半圆围绕圆心旋转能够覆盖平面内最多的点)
Transmitters Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4955 Accepted: 2624 Desc ...
- poj2181 jumping cow
umping Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7579 Accepted: 4559 Descr ...
- 树莓派3b入门教程
原文地址:传送门 这篇教程将带您一起玩转树莓派3(Raspberry Pi 3).和普通PC一样,拿到新设备第一件事就是要给它安装一个操作系统,并做一些初始化的操作.比PC简单的是,树莓派是一个固定配 ...
- Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现
栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...