在单个语句中创建和调用匿名函数
Posted
技术标签:
【中文标题】在单个语句中创建和调用匿名函数【英文标题】:Creating and invoking an anonymous function in a single statement 【发布时间】:2011-04-06 01:22:22 【问题描述】:一个 php 闭包或匿名函数用于创建函数而不指定它的名称。
是否可以像在 javascript 中那样在不分配标识符的情况下调用它们? 例如
(function()
echo('anonymous function');
)();
在定义匿名函数时,use
构造的正确用法是什么?匿名函数在可访问私有属性的公共方法中的状态如何?
$anon_func =
function($my_param) use($this->object_property) //use of $this is erroneous here
echo('anonymous function');
;
【问题讨论】:
闭包并不完全等同于匿名函数,尽管 PHP 中的匿名函数属于Closure
类型。让你知道。
当您尝试第二个代码示例时,确切的错误是什么? “错误”有点不具体。
不能使用 $this 作为词法变量
OP:由于 PHP 5.4 的变化,我已经更新了我的答案;不要问我他们为什么这样做。 cc @BoltClock
【参考方案1】:
PHP 7 添加了执行此操作的功能。
这段代码:
(function() echo "This works as expected in PHP 7.\n"; )();
在 PHP 7 中可以正常工作。(在任何 PHP 5.x. 版本中仍然无法正常工作)
【讨论】:
【参考方案2】:call_user_func(function() use(closure-vars) ... );
【讨论】:
OP 如何使闭包可以访问类属性? op可以通过use语句创建对象的引用传递给闭包,即:$obj = $this; call_user_func(function() 使用 ($obj))。这样他就可以访问闭包内的类属性和方法。有点 hack,但它是 PHP 5.4 到来之前我们拥有的最好的。【参考方案3】:是否可以在没有的情况下调用它们 像我们一样分配给标识符 JavaScript 吗?例如
PHP 5.x 中没有;除非当您的方法将回调作为参数时计算它。例如:
$square = array_map(function ($v) return $v*$v; , $array);
use的正确用法是什么 在定义匿名的同时构造 功能
use
关键字指示应将当前词法范围中的哪些变量导入闭包。您甚至可以通过引用传递它们并更改正在传递的变量,例如:
$total = 0;
array_walk($array, function ($v) use (&$total) $total += $v; );
// $total is now the sum of elements in $array
匿名状态是什么 在公共方法中使用 访问私有属性?
在类中定义的闭包可以完全访问其所有属性和方法,包括私有的,无需通过 PHP 5.4 中的关键字 use
导入 $this
:
// this works fine in PHP 5.4
$anon_func =
function($my_param)
$thing = $my_param + $this->object_property;
echo('anonymous function');
;
请注意,由于某些奇怪的原因,在闭包 was removed in PHP 5.3 中支持 $this
。在此版本中,您可以使用以下方法解决此限制:
// a workaround for PHP 5.3
$temp = $this;
$anon_func =
function($my_param) use ($temp)
$thing = $my_param + $temp->object_property;
echo('anonymous function');
;
但这只能让您访问公共成员,尝试访问私有成员仍然会给您一个错误。
另请注意,无论 PHP 版本如何,尝试导入 $this
(通过 use
)都会导致致命错误 Cannot use $this as lexical variable
。
【讨论】:
+1 但是,在 PHP 中无法自行调用像(function() )();
这样的匿名函数,原因可能与 Marc B 指出的同样的原因,数组取消引用也不可行。
@BoltClock BTW 数组解引用(例如:function foo() return $someArray;
、$var = foo()['bar']
)也适用于 PHP 5.4【参考方案4】:
看起来不像,因为它们仍然必须使用 function()
表示法声明,并且在我的 5.3.2 安装中,尝试您的示例概念会返回 unexpected '('
语法错误。闭包上的doc page 也没有提及。
也许一旦他们修补解析器以允许 somefunction()[2]
数组取消引用,这将成为可能。
【讨论】:
数组解引用已添加到PHP 5.4,但您仍然不能在声明后立即调用匿名函数。【参考方案5】:示例 1
(new class
function __invoke($n)
echo "in PHP 7.\n";
)(0);
示例 2
(function() echo "in PHP 7.\n"; )();
示例 3
call_user_func(function() echo "in php> 5.6\n"; );
【讨论】:
以上是关于在单个语句中创建和调用匿名函数的主要内容,如果未能解决你的问题,请参考以下文章