PHP闭包

Wesley13 等级 149 0 0
标签: 闭包php

转载自

php的闭包(Closure)也就是匿名函数。是PHP5.3引入的。

闭包的语法很简单,需要注意的关键字就只有use,use意思是连接闭包和外界变量。

1

2

3

$a  = function () use ( $b ) {

}

闭包的几个作用:

1 减少foreach的循环的代码

比如手册http://php.net/manual/en/functions.anonymous.php 中的例子Cart

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<?php

// 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。

// 其中有一个方法用来计算购物车中所有商品的总价格。该方法使用了一个closure作为回调函数。

class  Cart

{

const  PRICE_BUTTER  = 1.00;

const  PRICE_MILK    = 3.00;

const  PRICE_EGGS    = 6.95;

protected    $products  = array ();

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 )

{

$pricePerItem  = constant( __CLASS__  . "::PRICE_"  .

strtoupper ( $product ));

$total  += ( $pricePerItem  * $quantity ) * ( $tax  + 1.0);

};

array_walk ( $this ->products, $callback );

return  round ( $total , 2);;

}

}

$my_cart  = new  Cart;

// 往购物车里添加条目

$my_cart ->add( 'butter' , 1);

$my_cart ->add( 'milk' , 3);

$my_cart ->add( 'eggs' , 6);

// 打出出总价格,其中有 5% 的销售税.

print  $my_cart ->getTotal(0.05) . "\n" ;

// The result is 54.29

?>

这里如果我们改造getTotal函数必然要使用到foreach 

2 减少函数的参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function  html ( $code  , $id = "" , $class = "" ){

if  ( $id  !== "" ) $id  = " id = \"$id\""  ;

$class  = ( $class  !== "" )? " class =\"$class\"" : ">" ;

$open  = "<$code$id$class" ;

$close  = "</$code>" ;

return  function  ( $inner  = "" ) use  ( $open , $close ){

return  "$open$inner$close" ;};

}

如果是使用平时的方法,我们会把inner放到html函数参数中,这样不管是代码阅读还是使用都不如使用闭包

3 解除递归函数

1

2

3

4

5

6

7

8

9

10

<?php

$fib  = function ( $n ) use (& $fib ) {

if ( $n  == 0 || $n  == 1) return  1;

return  $fib ( $n  - 1) + $fib ( $n  - 2);

};

echo  $fib (2) . "\n" ; // 2

$lie  = $fib ;

$fib  = function (){ die ( 'error' );}; //rewrite $fib variable

echo  $lie (5); // error   because $fib is referenced by closure

注意上题中的use使用了&,这里不使用&会出现错误 fib( n-1)是找不到function的(前面没有定义fib的类型)

所以想使用闭包解除循环函数的时候就需要使用

1

2

3

4

<?php

$recursive  = function  () use  (& $recursive ){

// The function is now available as $recursive

}

这样的形式

4 关于延迟绑定

如果你需要延迟绑定use里面的变量,你就需要使用引用,否则在定义的时候就会做一份拷贝放到use中

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

$result  = 0;

$one  = function ()

{ var_dump( $result ); };

$two  = function () use  ( $result )

{ var_dump( $result ); };

$three  = function () use  (& $result )

{ var_dump( $result ); };

$result ++;

$one (); // outputs NULL: $result is not in scope

$two (); // outputs int(0): $result was copied

$three (); // outputs int(1)

使用引用和不使用引用就代表了是调用时赋值,还是申明时候赋值

收藏
评论区

相关推荐

PHP程序员必须会的 45 个PHP 面试题(第三部分)
Q25:此代码将返回什么?解释结果。 主题:PHP 难度:⭐⭐⭐ 考虑代码。结果将返回什么? $something 0; echo ('password123' $something) ? 'true' : 'false'; 答案是true。您永远不要将其用于字符串比较。即使将字符串与字符串进行比较,PHP也会将它们隐式转
半小时掌握Android Gradle
目前国内对Android领域的探索已经越来越深,不少技术领域如插件化、热修复、构建系统等都对Gradle有迫切的需求,不懂Gradle将无法完成上述事情。所以Gradle必须要学习。 Gradle 里的几乎任何东西都是基于这两个基础概念: task project 掌握了这两个,你就掌握了一大半的 Gradle 知识了。 首先讲 Task
Groovy 集合与闭包
Groovy 集合 在 Groovy 提供的所有方便的快捷方式和功能中,最有帮助的一个可能就是内置的 集合。回想一下在 Java 编程中是如何使用集合的 — 导入 java.util 类,初始化集合,将项加入集合。这三个步骤都会增加不少代码。 而 Groovy 可以直接在语言内使用集合。在 Groovy 中,不需要导入专门的类,也不需要初始化对象。集合是语
彻底理解js闭包
在文章开头,我先放出MDN给出的定义: 闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。 现在不需要看懂它,我会在第一个例子中解释清楚它的意思。让我们开始吧! 2018.3.20更新:现在MDN上的定义已经改为:"A closure is the comb
Python 中的闭包
闭包定义: 如果在一个内部函数里,对在外部作用于(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包 Python 中的闭包 原文出处: 田小计划(http://www.cnblogs.com/wilber2013/p/4658894.html) 闭包(closure)是函数式编程的重要的语法结构
重学JavaScript(函数)闭包
序言学习JavaScript切勿好高骛远。正所谓贪多嚼不烂,前端标准和工具这几年的飞速发展,以及不时冒出的“新鲜玩意”让众多前端从业者惊呼:“学不动啦学不动啦!学习速度跟不上技术发展速度!我感到手忙脚乱、力不从心……"如果你有以上“症状”,请勿着急,这不过是你内心不安造成的。你为何追新?你又何苦追新?在根基不牢的情况下,就算盖楼盖到18层,再往上堆一块砖,都
小记面试题-2021
CSS类 1.解释浮动及其工作原理浮动的元素可以向左或者向右移动,直到它的外边缘碰到包含元素(父元素)或另一个浮动元素的边框为止。要想使元素浮动,必须为元素设置一个宽度。虽然浮动的元素已不在文档流中, 但是它浮动后所处的位置依然在浮动之前的水平方向上。因为浮动元素不在文档流中,所以文档流中的块元素表现的就像浮动元素不存在一样,下面的元素会填补原来的位置。有些
go 学习笔记之10 分钟简要理解 go 语言闭包技术
**闭包**是主流编程语言中的一种**通用技术**,常常和**函数式编程**进行强强联合,本文主要是介绍 `Go` 语言中什么是闭包以及**怎么理解闭包**. 如果读者对于 `Go` 语言的闭包**还不是特别清楚**的话,可以**参考上一篇文章** [go 学习笔记之仅仅需要一个示例就能讲清楚什么闭包](https://www.oschina.net/ac
JS 闭包(内存溢出与内存泄漏)(垃圾回收机制)
**1.有关闭包定义** 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的 方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量 闭包的特性: 函数内再嵌套函数 内部函数可以引用外层的参数和变量 参数和变量不会被垃圾回收机制回收
PHP匿名函数及闭包
匿名函数在编程语言中出现的比较早,最早出现在Lisp语言中,随后很多的编程语言都开始有这个功能了, 目前使用比较广泛的Javascript以及C#,PHP直到5.3才开始真正支持匿名函数,C++的新标准C++0x也开始支持了。 匿名函数是一类不需要指定标示符,而又可以被调用的函数或子例程,匿名函数可以方便的作为参数传递给其他函数,最常见应用是作为回调函数
PHP匿名函数及闭包(精讲)
匿名函数在编程语言中出现的比较早,最早出现在Lisp语言中,随后很多的编程语言都开始有这个功能了, 目前使用比较广泛的JavaScript以及C#,**PHP直到5.3才开始真正支持匿名函数**,C++的新标准C++0x也开始支持了。 **匿名函数是一类不需要指定标示符,而又可以被调用的函数或子例程**,匿名函数可以方便的作为参数传递给其他函数,最常见应
PHP闭包
### [转载自](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.cnblogs.com%2Fyjf512%2Farchive%2F2012%2F10%2F29%2F2744702.html) ### ### php的闭包(Closure)也就是匿名函数。是PHP5.3
JavaScript函数——闭包
### 闭包 #### 概念 只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁 **例子** function outer(){ var localVal = 30; return localVal; }
Python嵌套函数 闭包
1\. 什么是嵌套函数 -----------   嵌套函数就是在函数中定义函数,英文叫`nested function` def outer(x):    def inner():        print(x)    inner() 这也很好理解,在函数`outer`中定义了另外一个函数`inner`,而`inner`也必须在`outer`
swift闭包表达式和尾随闭包
我们从一个Swift函数说起。并以此为例子。 Swift的标准库提供了一个叫做sorted(by:)的方法,会根据你**提供的排序闭包**将已知类型的数组的值进行排序。一旦它排序完成,sorted(by:)方法会返回与原数组类型大小完全相同的一个新数组,该数组的元素是已排序好的。原始数组不会被sorted(by:)方法修改。 我们以soted方法为例子