首页 > 作文

PHP 核心特性 – 匿名函数

更新时间:2023-04-07 21:09:21 阅读: 评论:0

提出

在匿名函数出现之前,所有的函数都需要先命名才能使用

1 function increment($value)2 {3     return $value + 1;4 }5 6 array_map('increment', [1, 2, 3]);

有的时候函数可能只需要高中语文成语使用一次,这时候使用匿名函数会使得代码更加简洁直观,同时也避免了函数在其他地方被使用
1 array_map(function($value){2     return $value + 1;3 }, [1, 2, 3]);

定义和使用

php 将闭包和匿名函数视为同等概念(本文统称为匿名函数),本质上都是伪装成函数的对象

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

1 $greet = function(string $name){2     echo "hello {$name}";3 }4 5 $greet("jack") // hello jack

所有的匿名函数都是closure对象的实例

$greet instanceof closure // true

对象并没有什么父作用域可言,所以需要使用u来手动声明使用的变量,

1 $num = 1;2 $func = function() u($num){3     $num = $num + 1;4     echo $num;5 }6 $func();  // 27 echo $num;  // 还第一次学游泳是 1

如果要让匿名函数中的变量生效,需要使用引用传值

1 $num = 1;2 $func = function() u(&$num){3     $num = $num + 1;4     echo $num;5 }6 $func();  // 27 echo $num;  // 2

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

 1 class foo { 2     public function bar() 3     {    4         return function() { 5             return $this; 6         }; 7     } 8 } 9 10 $foo = new foo();11 $obj = $foo->bar(); // closure()12 $obj();   // foo

如果不想让自动绑定生效,可使用静态匿名函数

 1 class foo { 2     public function bar() 3  支点教育   {    4         return static function() { 5             return $this; 6         }; 7     } 8 } 9 $foo = new foo();10 $obj = $foo->bar(); // closure()11 $obj();   // using $this when not in object context
十八岁成人礼

匿名函数的本质

匿名函数的本质是closure对象,包括了以下五个方法

1 closure {2     private __construct ( void )3     public static bind ( closure $closure , object $newthis [, mixed $newscope = "static" ] ) : closure4     public bindto ( object $newthis [, mixed $newscope = "static" ] ) : closure5     public call ( object $newthis [, mixed $... ] ) : mixed6     public static fromcallable ( callable $callable ) : closure

}

__construct– 防止匿名函数被实例化

墨镜女头像
$closure = new \closure();// php error:  instantiation of 'closure' is not allowed

closure::bindto– 复制当前匿名函数对象,绑定指定的$this对象和类作用域。通俗的说,就是手动将匿名函数与指定对象绑定,利用这点,可以扩展对象的功能。

 1 // 定义商品类 2 class good { 3     private $price; 4  5     public function __construct(float $price) 6     { 7         $this->price = $price; 8     } 9 }10 11 // 定义一个匿名函数,计算商品的促销价12 $adddiscount = function(float $discount = 0.8){13     return $this->price * $discount;14 }15 16 $good = new good(100);17 18 // 将匿名函数绑定到 $good 实例,同时指定作用域为 good19 $count = $adddiscount->bindto($good, good::class); 20 $count(); // 8021 22 // 将匿名函数绑定到 $good 实例,但是不指定作用域,将无法访问 $good 的私有属性23 $count = $adddiscount->bindto($good); 24 $count(); // 报错

closure::bindbindto方法的静态版本,有两种用法:

用法一:实现与bindto方法同样的效果

$count = \closure::bind($adddiscount, $good, good::class); 

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

 1 // 商品库存为 10 2 class good { 3     static $num = 10; 4 } 5  6 // 每次销售后返回当前库存 7 $ll = static function() { 8     return"当前库存为". --static::$num ; 9 };10 11 // 将静态匿名函数绑定到 good 类中12 $sold = \closure::bind($ll, null, good::class);13 14 $sold(); // 当前库存为 915 $sold(); // 当前库存为 8

call– php 7 新增的call方法可以实现绑定并调用匿名函数,除了语法更加简洁外,性能也更高

1 // call 版本2 $adddiscount->call($good, 0.5);  // 绑定并传入参数 0.5,结果为 503 4 // bindto 版本5 $count = $adddiscount->bindto($good, good::class); 6 $count(0.5); // 50

fromcallable– 将给定的callable函数转化成匿名函数

 1 class good { 2     private $price; 3  4     public function __construct(float $price) 5     { 6         $this->price = $price; 7     } 8 } 9 10 function adddiscount(float $discount = 0.8){11     return $this->price * $discount;12 }13 14 $closure = \closure::fromcallable('adddiscount');15 $good = new good(100);16 $count = $closure->bindto($good);  17 $count = $closure->bindto($good, good::class);   // 报错,不能重复绑定作用域18 $count(); // 报错,无法访问私有属性

fromcallable等价于

1 $reflexion = new reflectionfunction('adddiscount');2 $closure = $reflexion->getclosure();

这里有一点需要特别注意的是,无论是fromcallable转化成的闭包,还是使用反射得到的闭包,在使用bindto时,如果第二个参数指定绑定类,会报错

cannot rebind scope of closure created by reflectionfunctionabstract::getclosure()

 
        

本文发布于:2023-04-07 21:09:19,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/9c5af0ec07c5764b0b48146e0c04dd74.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:PHP 核心特性 – 匿名函数.doc

本文 PDF 下载地址:PHP 核心特性 – 匿名函数.pdf

标签:函数   绑定   对象   报错
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图