接触PHP一段时间以来,我一直以为这是一种基于函数式编程的语言是没有闭包这种东西的,但事实上却颠覆了我的想法,PHP竟然有闭包,下面我们一起来接触一下PHP的所谓的闭包。

根据PHP官网的定义来看,闭包(closure)又可以叫做匿名函数(Anonymous function),其实我们知道在JS中,闭包和匿名函数有着一定的区别,但是在PHP中却等同了,那么这肯定有一些区别的,那么我们和JS当中的闭包对比的来看看。

1、语句结构

在JS中,闭包和普通的函数定义没有什么区别,但是在PHP中,由于存在函数内部不能访问全局作用的,所以就需要一种可以引入上一级作用域的语法结构,这种就是

function () use () {}

将需要引入到这个函数作用于内的变量写入到use的括号里面就可以了,举个例子

<?php

$a = 1;

$closure = function () use ($a) {
echo $a;
}; $closure(); ?>

输出的结果为

1

这次就实现了闭包的功能了,可以和上级作用域产生了联系了

2、变量执行的时候是运行时赋值还是函数声明的时候赋的值?

学过JS的到这里一定认为这个$a变量当变化的时候,根据JS引用的理论,函数执行的结果也是变化的,但事实究竟是这样么?看例子:

<?php

$a = 1;

$closure = function () use ($a) {
echo $a;
}; $closure(); $a=2; $closure(); ?>

大家猜猜结果会是什么?

1 1

哎??为什么不是 1 2 呢?

因为对于PHP来说的闭包当声明闭包的时候,就已经将值重新开辟了一块内存赋值给了use中的$a所以,不过外部的$a怎么变,闭包执行的结果是不变的,那么我们怎么能让他变化呢?

先给大家一个提示,PHP实现闭包的本质其实是将这个特殊的函数转换成了一个类。

说到这里,大家是不是有一点明白了呢?既然是类,那么我们可以使用引用来传递use当中的值。

让我们再试一下

<?php

$a = 1;

$closure = function () use (&$a) {//注意这里,加了一个&
echo $a;
}; $closure(); $a=2; $closure(); ?>

再运行一下看看

1 2

这次结果对了吧。

不仅如此,引用之后,如果在闭包当中修改引入的变量值,原本的变量的值也会修改的,但是不过不加&,那么在闭包中修改变量的值得时候,即使这次修改有效了,下次重新运行闭包函数后又会回到之前的值,相当于没有修改。举个例子:

不加&:

<?php
$a = 1;
$closure = function () use ($a) {
$a++;
echo $a,' ';
};
$closure();
$closure();
$a=-5;
$closure();
$closure();
?>

输出为:

2 2 2 2

加了&之后

输出为

2 3 -4 -3

总结:

对应PHP中的闭包,和JS中的闭包还是有本质的区别的,JS的闭包是语言原生支持的,所以感觉比较符合人的思考方式,而PHP得闭包就是将闭包的这种特性抽象成了类的方式,然后以类的形式进行处理,毕竟是抽象出来的,还不是很符合人们的思考方式。

在接触了PHP的闭包之后,我深深的觉得PHP真是杂啊………………

PS:

1、不要忘记了在闭包的赋值语句最后面的分号,毕竟这是一个语句,还要是有分号的。

2、对于函数的传入参数等东西,和普通的参数写法是一样的。

3、要注意函数调用的时候不要忘记了$,因为闭包函数的本质还是一个变量的,不过是一个可以执行的变量了而已。如果去掉$,PHP解释器将会认为这是一个函数而不是一个闭包函数从而出错。

4、除了上面的那几点和JS的不同以外,其他的都是可以的,比如可以作为函数的返回值等等的内容。

PHP中的闭包小谈的更多相关文章

  1. js 中继承方式小谈

    题外话 前段时间面试中笔试题有这道题目: 请实现一个继承链,要求如下: 构造函数A():构造函数中有consoleA方法,可以实现console.log("a") 实例对象 a:a ...

  2. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  3. Javascript中的闭包(转载)

    前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...

  4. 狗日的Javascript中的闭包

    前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...

  5. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  6. 【Unity游戏开发】浅谈Lua和C#中的闭包

    一.前言 目前在Unity游戏开发中,比较流行的两种语言就是Lua和C#.通常的做法是:C#做些核心的功能和接口供Lua调用,Lua主要做些UI模块和一些业务逻辑.这样既能在保持一定的游戏运行效率的同 ...

  7. 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包

    浅谈 .NET 中的对象引用.非托管指针和托管指针   目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...

  8. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  9. 关于for循环中的闭包问题

    还是昨天的那个简单的小项目,已经花了一天的时间了 - - .从&&的用法,到CSStext,到今天马上要谈的闭包(closure),通过一个小东西,真真发现了自己的各方面不足.昨天发完 ...

随机推荐

  1. js node.children与node.childNodes与node.firstChild,node,lastChild之间的关系

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/06/js-node-children%e4%b8%8enode-childnodes ...

  2. Spring Boot国际化支持

    本章将讲解如何在Spring Boot和Thymeleaf中做页面模板国际化的支持,根据系统语言环境或者session中的语言来自动读取不同环境中的文字. 国际化自动配置 Spring Boot中已经 ...

  3. Mint安装配置Sublime Text3

    1.注册码: Sublime Text 3 3126 注册码 2.安装Package Control组件: 按Ctrl+`调出console(注:安装有QQ输入法的这个快捷键会有冲突的,输入法属性设置 ...

  4. Python之实现一个优先级队列

    问题 怎样实现一个按优先级排序的队列? 并且在这个队列上面每次 pop 操作总是返回优先级最高的那个元素 解决方案 下面的类利用 heapq 模块实现了一个简单的优先级队列: import heapq ...

  5. phpstorm提示phalcon语法

    先安装phalcon,将phalcon的扩展php_phalcon.dll添加到PHP的ext目录下,这个不做赘述,网上教程很多 下面直接安装phalcon-devtools, 1,分别下载phalc ...

  6. tcp - 传输控制协议 (TCP)

    总缆 SYNOPSIS #include <sys/socket.h> #include <netinet/in.h> tcp_socket = socket(PF_INET, ...

  7. 线程池——Executors

    一 Executor框架 为了更好地控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制.它们都在java.util.concurrent包中,是JDK并发包的核心.其 ...

  8. ApiCloud如何一键真机测试

    首先假设你已经有了APICloud账号,并创建了App项目. 需要注意的是,手机和电脑需要连接在同一wifi环境下. 第一步 下载自定义Loader 进入“开发控制台” 点击我们的项目 选择模块,再选 ...

  9. HTML5中的Canvas和SVG

    Canvas 和 SVG 都允许我们在浏览器中创建图形,但是它们在根本上是不同的. 1 SVG SVG 是一种使用 XML 描述 2D 图形的语言. SVG 基于 XML,这意味着 SVG DOM 中 ...

  10. 【Redis】分布式锁RedLock

    普通实现 说道Redis分布式锁大部分人都会想到: 1.setnx+lua, 2.setkey value px milliseconds nx. - 获取锁(unique_value可以是UUID等 ...