iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >php 闭包
  • 931
分享到

php 闭包

php开发语言 2023-09-02 07:09:00 931人浏览 安东尼
摘要

一、概念说明 通常定义PHP函数时,都会指定一个函数名,这样的函数可以称为具名函数,但实际上php也支持定义没有函数名的函数,这类函数被称为闭包,也叫匿名函数,其本质是 Closure 类对象,类摘要

一、概念说明

通常定义PHP函数时,都会指定一个函数名,这样的函数可以称为具名函数,但实际上php也支持定义没有函数名的函数,这类函数被称为闭包,也叫匿名函数,其本质是 Closure 类对象,类摘要如下

// 类用final修饰,防止定义子类final class Closure {    // 构造函数被定义为私有,防止匿名函数被实例化    private __construct ( void )    public static bind ( Closure $closure , object $newthis [, mixed $newscope = "static" ] ) : Closure    public bindTo ( object $newthis [, mixed $newscope = "static" ] ) : Closure    public call ( object $newthis [, mixed $... ] ) : mixed    public static fromCallable ( callable $callable ) : Closure    public __invoke( ...$values): mixed}

二、成员函数说明

2.1 __invoke

当以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用,直接调用__invoke 也是一样会执行编写的函数体,下面是示例

function callInvoke(){    $func = function ($name,$age){        echo __FUNCTION__," name=$name,age=$age\n";    };    $func();    $func->__invoke("kate",100);}callInvoke();

输出结果

{closure} name=kate,age=100{closure} name=kate,age=100

所以,编写的匿名函数函数体可以被认为是 __invoke 函数的函数体。

2.2 bindTo

返回一个新的闭包,新的闭包绑定了指定的 t h i s 对 象 和 类 作 用 域 。 也 就 是 将 匿 名 函 数 中 的 this 对象和类作用域。也就是将匿名函数中的 thisthis绑定为所给的对象,从而可以直接使用其成员变量和成员函数,反过来,相当于指定的对象临时增加了一个新的方法,只不过只能用函数调用的方式来调用,某种程度上扩展了对象的功能。

// 定义商品类class Good {    private $price;    public function __construct(float $price)    {        $this->price = $price;    }}// 定义一个匿名函数,计算商品的促销价$aDDDiscount = function(float $discount = 0.8){    return $this->price * $discount;}$good = new Good(100);// 将匿名函数绑定到 $good 实例,同时指定作用域为 Good$count = $addDiscount->bindTo($good, Good::class); $count(); // 80// 将匿名函数绑定到 $good 实例,但是不指定作用域,将无法访问 $good 的私有属性$count = $addDiscount->bindTo($good); $count(); // 报错

2.3 bind

该函数是 bindTo 方法的静态版本,有两种用法:
用法一:实现与 bindTo 方法同样的效果

$count = \Closure::bind($addDiscount, $good, Good::class); 

用法二:将匿名函数与类(而不是对象)绑定,此时第二个参数需要设置为 null

// 商品库存为 10class Good {    static $num = 10;}// 每次销售后返回当前库存$sell = static function() {    echo "当前库存为". --static::$num,"\n" ;};// 将静态匿名函数绑定到 Good 类中$sold = \Closure::bind($sell, null, Good::class);$sold(); $sold();

输出如下

当前库存为 9当前库存为 8

2.4 call

call 方法是PHP 7 新增的,可以实现绑定并调用匿名函数,语法更加简洁,性能更高。下面是两种方式的示例代码。

// call 版本$addDiscount->call($good, 0.5);  // 绑定并传入参数 0.5,结果为 50// bindTo 版本$count = $addDiscount->bindTo($good, Good::class); $count(0.5); // 50

2.5 fromCallable

PHP语言中callable 是一种类型,表示可以被直接调用,包括命名函数、闭包、类成员函数和类静态成员函数。fromCallable可以一个 callable 函数转化成匿名函数,

class Good {    private $price;    public function __construct(float $price)    {        $this->price = $price;    }}function addDiscount(float $discount = 0.8){    return $this->price * $discount;}$closure = \Closure::fromCallable('addDiscount');$good = new Good(100);$count = $closure->bindTo($good);  $count = $closure->bindTo($good, Good::class);   // 报错,不能重复绑定作用域$count(); // 报错,无法访问私有属性// fromCallable 等价于$reflexion = new ReflectionFunction('addDiscount');$closure = $reflexion->getClosure();

测试来看,无论是 fromCallable 转化成的闭包,还是使用反射得到的闭包,在使用 bindTo 时,如果第二个参数指定绑定类,就会报下面的错错误

Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()

也就是第二个参数必须为null,接下来又会发现,如果闭包函数访问了私有属性也会报错,这样一来,这个函数能做的事情其实很少。从下面两篇官方文档来看,此函数可以用来将类的 private/protected 成员函数转为闭包,从而在类外部直接调用。

Closure::fromCallable
php新特性介绍

总结来说,这个函数挺鸡肋的。

三、使用

匿名函数的本质是对象,因此可将匿名函数赋值给某一变量。

3.1 使用外部变量

通过 use 声明的变量可以在匿名函数内部使用,如果声明的是引用,那么在匿名函数中修改变量后,外部变量会同步修改。

$num = 1;$func = function() use($num){    $num = $num + 1;    echo $num;}$func();  // 2echo $num;  // 还是 1// 要让匿名函数中对外部变量的修改在闭包结束后仍然生效,需要使用引用传值$num = 1;$funcRef = function() use(&$num){    $num = $num + 1;    echo $num;}$funcRef();  // 2echo $num;  // 2

3.2 自动绑定$this到当前类

从 PHP 5.4 开始,在类里面使用匿名函数时,匿名函数的 $this 将自动绑定到当前类

class Foo {    public function bar()    {        return function() {            return $this;        };    }    public function getAge(){        return 100;    }}function testThis(){    $foo = new Foo();    $obj = $foo->bar();    var_dump($obj);//    var_dump($obj()->getAge());}testThis();

输出结果如下

object(Closure)#2 (1) {  ["this"]=>  object(Foo)#1 (0) {  }}int(100)

如果不想让自动绑定生效,可以使用静态匿名函数,此时返回的闭包中不能使用 $this,否则一调用就会报下面的 Fatal error

class FooStatic{    public function bar()    {        return static function () {            return $this;        };    }    public function getAge()    {        return 100;    }}function testStaticThis(){    $foo = new FooStatic();    $obj = $foo->bar(); // Closure()    var_dump($obj);    $obj(); // Fatal error: Using $this when not in object context}testStaticThis();

因此静态匿名函数实际上是绑定了整个类,可以通过static关键字访问类静态变量,示例代码如下

class FooStatic{    static $quantity = 10;    public function bar()    {        return static function () {            echo static::$quantity,"\n";        };    }}$foo = new FooStatic();$obj = $foo->bar(); // Closure()var_dump($obj);$obj();

输出如下

object(Closure)#2 (0) {}10

参考

php手册 https://www.php.net/manual/zh/class.closure.php
心智极客 Https://learnku.com/articles/35863

来源地址:https://blog.csdn.net/afterlife_union/article/details/128019382

--结束END--

本文标题: php 闭包

本文链接: https://www.lsjlt.com/news/390173.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • php 闭包
    一、概念说明 通常定义php函数时,都会指定一个函数名,这样的函数可以称为具名函数,但实际上PHP也支持定义没有函数名的函数,这类函数被称为闭包,也叫匿名函数,其本质是 Closure 类对象,类摘要...
    99+
    2023-09-02
    php 开发语言
  • 闭包
    返回函数不可以引用后续可能会发生变化的变量 如果引用,则返回函数的返回值是基于变量最新的值计算而得的 如循环变量i,如果返回函数体内用到了i,则i的值是最后一次循环的i的值 使用示例   返回函数引用循环变量   def count(...
    99+
    2023-01-31
  • 如何使用 PHP 闭包函数?
    闭包函数是匿名函数,可以访问其定义环境中的变量。其语法为 $closure = function ($arguments) { // 函数体}; 可以在函数中使用 use 语句显式声明...
    99+
    2024-04-16
    php 闭包函数 排列
  • python---闭包
    1.闭包理解 闭包定义:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包 2.必报的构成条件: 在函数嵌套(函数里面在定义函数)的前提下 内部函数使用了外部函...
    99+
    2023-09-02
    python numpy 开发语言 Powered by 金山文档
  • python闭包
    闭包    1,闭包是嵌套在函数中的    2,闭包是内层函数对外层函数的变量的引用(改变)    3,闭包需要将其作为一个对象返回,而且必须逐层返回闭包举例:    def wrapper():        name = "ghl"  ...
    99+
    2023-01-31
    python
  • python 闭包
    这里主要讲解我对于闭包的理解,不太深入,浅谈浅谈哈 1、说到闭包我就想先说函数名与变量之间的区别 def test(name): def test_in(): print(name) print(loca...
    99+
    2023-01-30
    python
  • python3 闭包
    1. 函数引用def test1(): print("--- in test1 func----") #调用函数 test1() #引用函数 ret = test1 print(id(ret)) print(id(test1...
    99+
    2023-01-31
  • PHP 5.3闭包语法的具体使用
    本篇内容介绍了“PHP 5.3闭包语法的具体使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP 5.3闭包语法就是一个匿名函数,它可以...
    99+
    2023-06-17
  • PHP 函数的链式调用和闭包
    是的,可以通过链式调用和闭包优化代码简洁性和可读性:链式调用可将函数调用链接为一个流畅接口。闭包可创建可重用代码块,并在函数外部访问变量。 PHP 链式调用和闭包:提升代码简洁性和可读...
    99+
    2024-04-13
    闭包 php 函数 链式调用 代码可读性
  • 如何在PHP中使用闭包函数
    PHP闭包函数是指在声明函数时所定义的函数体内部所使用的变量和外部环境中的变量形成一个封闭的作用域,这种函数又被称为匿名函数。闭包函数在PHP中被广泛应用,可以用于实现事件处理、回调等一系列功能。本文将介绍如何在PHP中使用闭包函数,以及一...
    99+
    2023-05-18
    函数编程 PHP编程 闭包函数
  • Python闭包与闭包陷阱举例详解
    目录1 什么是闭包2 闭包示例代码3 什么是闭包陷阱4 闭包陷阱代码实例4.2 第二组代码实例总结1 什么是闭包 在 Python 中,闭包是一种特殊的函数,它能够记住它所在的环境(...
    99+
    2023-01-28
    python中闭包的概念 python闭包详解 Python闭包
  • 闭包函数
    目录 什么是闭包?(掌握) 两种为函数传参的方式 闭包函数的应用(掌握) 回顾: 函数对象:可以将...
    99+
    2023-01-31
    函数
  • python闭包,count()
    ...
    99+
    2023-01-31
    python count
  • PHP闭包及Clourse类的作用是什么
    今天小编给大家分享一下PHP闭包及Clourse类的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。PHP Clou...
    99+
    2023-06-29
  • PHP闭包的解释以及实现方法
    本篇内容主要讲解“PHP闭包的解释以及实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PHP闭包的解释以及实现方法”吧!匿名函数提到闭包就不得不想起匿名函数,也叫闭包函数(closures...
    99+
    2023-06-17
  • php中闭包函数的作用是什么
    这篇文章给大家分享的是有关php中闭包函数的作用是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是闭包函数:在子函数内部使用通过use关键字使用父函数的变量,这种方式就是闭包函数格式:function&n...
    99+
    2023-06-15
  • 谈谈自己的理解:python中闭包,闭包
    闭包这个概念好难理解,身边朋友们好多都稀里糊涂的,稀里糊涂的林老冷希望写下这篇文章能够对稀里糊涂的伙伴们有一些帮助~请大家跟我理解一下,如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。闭包:   在一个外函...
    99+
    2023-01-31
    自己的 python 中闭包
  • JavaScript中的闭包
    一.什么是闭包 1.闭包的定义 闭包并不是JS特有的,因此可以从两个角度定义闭包。 1)计算机科学中 闭包又称为词法闭包(在进行词法分析的时候这个闭包就确定了),或者是函数闭包。是在支持头等函数的编程语言中(意思是函数作为一等公民的编程语言...
    99+
    2023-08-18
    javascript 前端 java
  • 闭包之谜:深入探讨 JavaScript 闭包的行为
    范围和作用域链 闭包的作用域链由以下作用域组成: 局部作用域:闭包函数自身的作用域,其中包含闭包中声明的变量。 闭包作用域:创建闭包的函数的作用域,其中包含闭包访问的变量。 全局作用域:浏览器窗口或 Node.js 全局环境。 闭包可...
    99+
    2024-03-14
    闭包
  • 分享js闭包
    这篇文章主要讲解了“分享js闭包”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分享js闭包”吧!## 闭包闭包是一个能读取其他函数内部变量的函数:1. ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作