PHP闭包

Wesley13
• 阅读 819

转载自

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)

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
PHP匿名函数及闭包
匿名函数在编程语言中出现的比较早,最早出现在Lisp语言中,随后很多的编程语言都开始有这个功能了,目前使用比较广泛的Javascript以及C,PHP直到5.3才开始真正支持匿名函数,C的新标准C0x也开始支持了。匿名函数是一类不需要指定标示符,而又可以被调用的函数或子例程,匿名函数可以方便的作为参数传递给其他函数,最常见应用是作为回调函数
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这