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";
PHP 闭包获取外部变量和global关键字声明变量的区别的更多相关文章
- 【python】为什么修改全局的dict变量不用global关键字
转自:http://my.oschina.net/leejun2005/blog/145911?fromerr=qnPCgI19#OSC_h4_8 为什么修改字典d的值不用global关键字先声明呢? ...
- ES5-ES6-ES7_let关键字声明变量
let命令的介绍 let是ECMAScript6中新增的关键字,用于声明变量.它的用法类似于var var a = 3 let b = 4 let变量的声明 let 命令的特点不允许在同一作用域下声明 ...
- C++ —— 类中static和const关键字声明变量的初始化方式总结
在类中声明变量/常量时,经常会用到static.const关键字.对于该变/常量的初始化问题,网上有许多相关文章,但是大多不够完善,或者存在错误.经过实际验证,总结如下: (注明:测试编译平台为VS2 ...
- javascript的var声明变量和不用var声明变量在全局作用域的区别;
在全局作用域下,使用var定义的变量不可以delete,没有var 定义的变量可以delete.也就说明隐含全局变量严格来说不是真正的变量,而是全局对象的属性,因为属性可以通过delete删除,而变量 ...
- Java如何声明变量?JS如何声明变量?
Java采用强类型变量检查,像C语言一样.所有变量在编译之前必须声明,而且不能使用没有赋值的变量.例如:int x;x=1234;char y='F';其中X=1234说明是一个整数,Y='F'说明是 ...
- 全局变量和局部变量(global关键字)
1.定义在函数外部的就是全局变量,它的作用域从定义处一直到文件结尾. 2.函数内定义的变量就是局部变量,它的作用域为函数定义范围内. 3.函数之间存在作用域互不影响. 4.函数内访问全局变量需要 gl ...
- Java(2)详解注释&关键字&常量&变量&标识符
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201497.html 博客主页:https://www.cnblogs.com/testero ...
- js声明变量的三种方式及作用域
js声明变量的三种方式及作用域 CreateTime--2017年9月11日17:19:11 Author:Marydon 一.参考链接 本篇文章的创作灵感来源于博主-奔跑的铃铛关于js中cons ...
- js声明变量的三种方式
JS 声明变量的三种方式 (1)使用变量步骤:a.声明-->b.赋值-->3.调用 正确用法: <script type="text/javascript"> ...
随机推荐
- (转)Spring boot(一):入门篇
https://www.cnblogs.com/ityouknow/p/5662753.html#!comments 构建微服务:Spring boot 入门篇 什么是Spring Boot Spri ...
- ajaxForm和ajaxSubmit 粘贴就可用
<!--To change this template, choose Tools | Templatesand open the template in the editor.-->&l ...
- UVA548-Tree(二叉树数组表示)
Problem UVA548-Tree Accept: 2287 Submit: 13947 Time Limit: 3000 mSec Problem Description You are to ...
- 浮动、清除浮动、BFC
一. 浮动 1. 浮动的定义 使元素脱离文档流,按照向左或向右的方向移动,直到它的外边缘碰到包含它的框或另一个浮动框为止. 脱离文档流就是在页面中不占位置了. 左浮动右浮动此处就不再赘述了. 2. 看 ...
- CSS3系列教程:HSL 和HSL
使用CSS3 HSL声明同样是用来设置颜色的.下一个呢? HSLA? 是的,这个和RGBA的效果是一样的. HSL声明使用色调Hue(H).饱和度Saturation(s)和亮度Lightness(L ...
- 上传文件异常 MultipartException
参考自 https://blog.csdn.net/u010429286/article/details/54381705 现象 上传文件报错 org.springframework.web.mul ...
- Java内存分配之堆、栈和常量池(转)
摘录自http://www.cnblogs.com/SaraMoring/p/5687466.html Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类 ...
- Python排序算法——希尔排序(Shell’s Sort)
有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10793487.html 一.希尔排序(Shel ...
- ubuntu 下使用 jsoncpp库
做项目的时候需要用c++解析json文件, 之前使用的是libjson 库, 但当g++ 开启 -std=c++11 选项时, 该库的很多功能不能用, 而且还有一些其他的问题, 不推荐使用. 后来采用 ...
- 奇怪的组数length属性
Java中的数组其实也是一个对象,但是确实是一个特殊的对象,实在是太特殊了,继承自Object, 多出一个属性length,改写了clone方法. 我debug了数组对象的运行时的Class对象, ...