PHP匿名函数(Closure)
缘由
这几天看了Martin Sikora写的《PHP Reactive Programming》的第一章Introduction to Reactive Programming,其中对函数式编程举例时的PHP代码把匿名函数玩出了花,所以下午看了下关于Closure的文档。
函数式编程
函数式编程(Functional Programming)是一种编程范式(Programming Paradigm)。
其要点有三:
- 消除函数副作用(Eliminating side effects)
由于非局部变量改变或跳出函数体的控制语句,而造成的函数*变量不满足交换率的作用。
- 变量不变性(Avoiding mutable data)
不改变非局部变量的状态,并且对于同样的输入,会造成相同的输出。
- 函数作为程序基本数据类型(First-class citizens and higher-order functions)
函数可以作为函数参数、被赋值和作为函数返回值。
PHP匿名函数(Closure)
当我们提起PHP匿名函数的时候,一般指的是下面这样的代码。
其中,$greet
其实是一个Closure对象。
文档中对Closure类进行了详细的描述,PHP 7.1版本之前,主要包含三个方法bind
,bindTo
,call
,这三个方法的区别主要是在于匿名函数对象中$this
的使用。
bind/bindTo
两个方法实现的功能类似,都是复制一个匿名函数对象,指定其$this
对象和类作用域。
以下仅就非静态方法bindTo
进行说明。
$newthis
指的是新的匿名函数对象中$this
所调用的对象,而$newscope
则会确定$this
中成员的可见性。
默认参数static
使用默认参数static
的情况如下:
这时候报错PHP Fatal error: Cannot access private property Foo::$_foo
,显然static
无法访问private属性_foo
。
类名或者对象
如果我们指定Baz对象为$this
,并将可见性设置为Baz的可见性。
这时候测试通过,新的$funcBaz
中的$this
可以访问Foo和Baz的私有属性。
当我们指定Baz对象为$this
,而将可见性设置为Foo的可见性时。
程序会报错PHP Fatal error: Cannot access private property Baz::$_baz
,这时候就无法访问Baz的私有属性了。
call
这个方法临时指定一个对象作为$this
,并用剩余参数调用匿名函数,返回值为匿名函数的返回值。
其他
这个类在PHP版本升级7之后有一些变动:
$newscope
在7.0.0版本后不能使用PHP内置的类- 7.1.0版本后新增加
Closure::fromCallable ( callable $callable )
方法,用以从callable
构造一个匿名函数并检查,如果不可call,则会抛出TypeError