PHP 闭包获取外部变量和global关键字声明变量的区别

最近在学习workerman的时候比较频繁的接触到回调函数,使用中经常会因为worker的使用方式不同,会用这两种不同的方式去调用外部的worker变量,这里就整理一下PHP闭包获取外部变量和global关键字声明变量的区别。

闭包

闭包是一个常见的概念,我们通常可以将其与回调函数配合使用,可以使代码更加简洁易读。

闭包可以通过拷贝的方式让函数使用父作用域中的变量。如:

$global = ‘hello‘;

$bbb = function()use($global){
    echo $global."\n";
};
$bbb();
//输出 ‘hello‘

global关键字声明变量

通过global声明变量同样可以使函数体调用到函数外部的变量,不过global与use不同,globle关键字会使创建一个与外部变量同名的引用,并且在函数内对变量作出修改同样会作用域外部变量。

$global = ‘hello‘;
$fun = function(){
    global $global;
    $global =‘ world‘;
    echo $global."\n";
};
$fun();
// 输出 ‘world‘

这里只是创建一个同名引用而已,并不会改变原本外部变量$global的作用域,也就是说在另外一个函数中调用该依旧需要声明或者使用闭包

$global = ‘hello‘;
$fun = function(){
    global $global;
    $global =‘ world‘;
    echo ‘a:‘.$global."\n";
};

$ccc = function(){
    echo ‘b:‘.$global;
};
$fun()
$ccc()
/*
输出
a: world

Notice: Undefined variable: global in xxxxxxx on line xx
*/

再稍微改一下代码,这样更容易对比闭包和global关键字声明变量这两种访问外部变量方式的区别。

<?php
$global = ‘hello‘;
$fun = function(){
    global $global;
    $global =‘world‘;
    echo ‘a:‘.$global."\n";
};

$bbb = function()use($global){
    $global = ‘china‘;
    echo ‘c:‘.$global."\n";
};

$fun();

echo ‘b:‘.$global."\n";
$bbb();
echo ‘d:‘.$global;

这里b和d两个输出可以看出来,global改变了外部变量的值,而闭包方式并没有。

输出:

a: world
b: world
c:china
d: world

最后再贴一个官方文档中比较经典的使用匿名函数,闭包与回调函数配合的例子:

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

print $my_cart->getTotal(0.05) . "\n";
时间: 2024-10-18 01:28:07

PHP 闭包获取外部变量和global关键字声明变量的区别的相关文章

飘逸的python - 为什么修改全局的dict变量不用global关键字

比如下面这段代码 s = 'foo' d = {'a':1} def f(): s = 'bar' d['b'] = 2 f() print s print d 为什么修改字典d的值不用global关键字先声明呢? 这是因为, 在s = 'bar'这句中,它是"有歧义的",因为它既可以是表示引用全局变量s,也可以是创建一个新的局部变量,所以在python中,默认它的行为是创建局部变量,除非显式声明global. 在d['b']=2这句中,它是"明确的",因为如果把d

【python】为什么修改全局的dict变量不用global关键字

转自:http://my.oschina.net/leejun2005/blog/145911?fromerr=qnPCgI19#OSC_h4_8 为什么修改字典d的值不用global关键字先声明呢? s = 'foo' d = {'a':1} def f(): s = 'bar' d['b'] = 2 f() print s # foo print d # {'a': 1, 'b': 2} 这是因为,在s = 'bar'这句中,它是“有歧义的“,因为它既可以是表示引用全局变量s,也可以是创建一

关于Javascript中通过var关键字声明变量和function关键字声明函数的笔记

一.概念 1.变量声明 在JavaScript中,变量一般通过var关键字(隐式声明,let关键字声明除外)进行声明,如下通过var关键字声明a,b,c三个变量(并给其中的a赋值): var a=1,b,c; //关键字显式声明变量a,b,c,并给a赋值console.log(a); //1 //由于b,c未定义变量类型,因此输出"undefined"console.log(b); //undefinedconsole.log(c); //undefined //如果变量未声明,则输出

在全局下用let声明变量和用var声明变量还是有区别的

sleep方法的作用是让当前线程暂停指定的时间(毫秒),sleep方法是最简单的方法,在上述的例子中也用到过,比较容易理解.唯一需要注意的是其与wait方法的区别.最简单的区别是,wait方法依赖于同步,而sleep方法可以直接调用.而更深层次的区别在于sleep方法只是暂时让出CPU的执行权,并不释放锁.而wait方法则需要释放锁. 最近两天在系统的复习性能测试方面的知识,结合之前的性能测试经验有了一些总结,希望写出来与大家分享,希望多提宝贵意见,共同进步~首先来说说性能测试:性能是软件的一种

1.为什么 要需要变量。二进制,方便,2.变量是什么 ,3.声明变量

原文地址:https://www.cnblogs.com/gzhbk/p/9656544.html

Kotlin声明变量

Kotin中的变量和大多数语言不同,与js相似.它的变量类型可以不需要强制指定,编译器可以自行推断出变量的类型.声明变量语法var or val 变量名[: 类型] = 值 声明变量 var a: Int = 1 println(a)             //1 自动推断类型.可以不指明类型,Kotlin可以自动推断其类型,但必须赋初始值 var b = 2 println(b)             //2 如果不给变量赋值,那么变量的类型不能省略 //var c            

【声明变量的规则】

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <script type="text/javascript"> 7 //声明变量以及命名规则 8 var a; 9 var b; 10 var c,d; 11 /*alert(a);*/ 12 //声明变量的同时并且赋值 1

0090 JS变量的使用:声明、赋值、初始化、语法扩展、命名规范

变量的声明 变量的赋值 7.1 声明变量 // 声明变量 var age; // 声明一个 名称为age 的变量 var 是一个 JS关键字,用来声明变量( variable 变量的意思 ).使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管. age 是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间. 7.2 赋值 age = 10; // 给 age 这个变量赋值为 10 =: 用来把右边的值赋给左边的变量空间中,此处代表赋值的意思 变量值是程序员保存到变量空

typedef声明变量也是一种求值过程

前言: 什么叫做:声明变量是求值过程?请看下面的声明, int i; 很简单,声明了个整型变量i,再看如下声明, int *p; 也很简单,立刻反应出来它是指向整型的指针,但是具体如何推倒出来的呢?其实在C语言中,变量的声明就是一种求值过程,把*p这部分声明看成表达式,对这个表达式的求值的结果是int类型,这样就可以倒推出p是指针整型的指针了,因为只有对指向整型的指针进行解引用操作才是整型类型!还有很多复杂的声明,都可以使用这种方法求其具体的类型. 下面让我们来验证typedef定义的新类型和普