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(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)

 

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

时间: 2024-09-08 10:27:41

PHP的闭包的相关文章

Swift使用闭包表达式

Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是后面有in关键字.Swift提供了多种闭包简化写法,这一节我们将介绍几种不同的形式.1.类型推断简化类型推断是Swift的强项,Swift可以根据上下文环境推断出参数类型和返回值类型.以下代码是标准形式的闭包:{(a:Int, b:Int) -> Int in    return a + b}Swift

python中的闭包用法实例详解

  这篇文章主要介绍了python中的闭包用法,以实例形式详细分析了Python中闭包的概念及相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了python中的闭包用法.分享给大家供大家参考.具体分析如下: 什么是闭包? 简单说,闭包就是根据不同的配置信息得到不同的结果 再来看看专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有另

JS闭包中的循环绑定处理程序

前几天工作中写前端js代码时,遇到了遍历元素给它添加单击事件.就是这个问题让 我整整调了一个下午.最后还是下班回家,上网查资料才知道怎么解决的. (PS:之前也在<jQuery基础教程>第四版中看过讲循环绑定处理程序的内 容,当时估计也没怎么用心看,所以没记起来.) 大神要是知道这类情况,可以关掉窗口,写这些主要是给像我一样的小白看的.谢谢!  先贴上错误的例子让大家看看.(例子里面用到jQuery,请导入jQuery库) <!DOCTYPE html PUBLIC "-//W

JavaScript——以简单的方式理解闭包

      闭包,在一开始接触JavaScript的时候就听说过.首先明确一点,它理解起来确实不复杂,而且它也非常好用.那我们去理解闭包之前,要有什么基础 呢?我个人认为最重要的便是作用域(lexical scope),如果对作用域和作用域链不理解的同学最好自己先去学一学,再回过头来,理解闭包,就更加轻松. 下面便直接进入主题. 我们知道一个函数是有作用域的,在函数内部定义的局部变量只有在函数内部才可以访问的到.一旦函数访问结束被销毁,局部变量随之也会销毁,无法 通过任何方式再次访问局部变量,除

javascript闭包

前言 闭包对于初学者而言一直是一个不太好理解的概念.最近在学习javascript的时候碰巧看到了关于这方面的讲解,自己才明白了许多,所以把它写出来分享给大家.当然,本文也是参考了很多blog和书籍,加上自己的理解写出来的,文章末尾会附上对应的参考文档. 基础知识  变量作用域 //javascript的变量作用域可以分为两种:全局变量和局部变量. //在函数内声明的变量就是局部变量,这个变量在函数体内可访问,在函数外部无法直接读取局部变量. //例如: var globalVariable =

JavaScript的“闭包”到底是什么

在JavaScripot函数闭包的定义中,一般都有一个outer 函数,一个inner函数.那么"闭包"到底是指outer函数呢,还是指inner函数? 从官方定义来看,并不清楚:A closure is a combination of a code block and data of a context in which this code block is created. 那么在下列函数中: function outerfunc(y) {             var int

JavaScript的“闭包”到底是什么(2)

我的上篇博客标题不对,造成一些误解.我认为博客的宗旨不是背教科书,而是分享研发心得.我的上篇标题因该改成"JavaScript 闭包的一个议题:它对outer scope 的影响",因为我没有严格地去分析闭包的定义,而是分析了实现闭包的其中一个语义问题. 讲清楚闭包是件麻烦事,我也没有看到什么关于JavaScript的权威性著作(比如像C++语言有 Bjarne Stroustrup的C++ programming language).所以除了苦读JavaScript语言国际标准<

js闭包的用途

我们来看看闭包的用途.事实上,通过使用闭包,我们可以做很多事情.比如模拟面向对象的代码风格:更优雅,更简洁的表达出代码:在某些方面提升代码的执行效率. 1 匿名自执行函数 我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处, 比如:别的函数可能误用这些变量:造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的). 除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一

深入理解js闭包

深入理解js闭包 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码

js中的闭包之我理解

闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的理解以及js内部解释器的运作 方式的描述,都是可以看出你js实际水平的.即使你没答对,也能让考官对你的水平有个评估.那么我先来说说我对js中的闭包的理解. 闭包是很多语言都具备的特性,在js中,闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等. 在理解闭包以前.最好