是否可以在不使用全局变量的情况下模拟 PHP 5.2.x 中的闭包?
是否可以在不使用全局变量的情况下模拟 PHP 5.2.x 中的闭包?我可以想到一种将所需变量作为额外参数传递给闭包的方法,但这感觉不是最佳实践。
有什么想法吗?
Is it possible to simulate closures in PHP 5.2.x not using globals? I could think of a way that would pass the desired variables as extra parameters to the closure but that just doesn't feel like best practice.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有趣的问题。我想说根本不可能,但让我们看看
引用IBM - PHP5.3 中的新增功能,第 2 部分
以及进一步(强调我的)
使用
global
将通过引用传递,尽管可以通过在use
子句中使用&
通过引用与闭包绑定变量,但它已经偏离了 5.3 默认行为。您可以复制全局变量以便按值使用它,例如
此外,创建函数时不会评估(绑定)全局变量的值(使用
create_function
时),但当函数运行时同样重要的是
这对于
global
关键字来说是不可能的,而且您也不能只使用$this
。使用create_function
定义函数体时,无法引用类中的属性。将导致
总结一下
虽然您可以创建从全局作用域导入变量的函数,但无法使用其他作用域的变量创建函数。而且因为从技术上讲,您在使用
create_function
时并不进行绑定,而是在执行创建的函数时进行导入,所以我想认为此限制使闭包成为 lambda。编辑:下面 Onno Marsman 提供的解决方案相当不错。它没有完全模拟闭包,但实现非常接近。
Interesting question. I'd say it's not possible at all, but let's see
Quoting IBM - What's new in PHP5.3, Part 2
and further (emphasis mine)
Using
global
would pass by reference and although it is possible to bind variables by reference with a closure by using&
in theuse
clause, it is already a deviation from the 5.3 default behavior.You could copy the global variable in order to use it by value though, e.g.
In addition, the value of the global variable (when using
create_function
) will not be evaluated (bound) when the function is created but when the function is runAlso important is
This is impossible with the
global
keyword and you also cannot just use$this
. There is no way to reference a property from a class when defining the function body withcreate_function
.will result in
To sum this up
While you can create a function importing a variable from the global scope, you cannot cannot create one using variables from another scope. And because you are technically not binding when using
create_function
but importing when the created function is executed, I'd like to argue this limitation makes the closure a lambda.EDIT: The solution offered by Onno Marsman below is pretty decent though. It doesn't fully simulate Closures, but the implementation is pretty close.
我的解决方案: http:// techblog.triptic.nl/simulated-closures-in-php-versions-prior-to-php-5-3/
但是,它确实将对象内的变量作为第一个参数传递给闭包。
My solution: http://techblog.triptic.nl/simulating-closures-in-php-versions-prior-to-php-5-3/
It does however pass the variables within an object to the closure as the first argument.
你的意思是像 http://en.wikipedia.org/wiki/Currying
然后< a href="http://zaemis.blogspot.com/2009/06/currying-in-php.html" rel="nofollow noreferrer">http://zaemis.blogspot.com/2009/06/currying-in -php.html
如果没有,没关系。 :-)
Do you mean Currying like http://en.wikipedia.org/wiki/Currying
Then http://zaemis.blogspot.com/2009/06/currying-in-php.html
If not, never mind. :-)
在一些特殊情况下您可以这样做。
如果您需要按值(而不是按引用)捕获变量,并且该值是简单的值类型,如数字、字符串或上述数组(而不是对象、资源和函数等引用类型),那么您可以简单地使用
var_export()
将其插入到函数定义中:如果您需要通过引用捕获变量以便在函数调用之间保持可变状态,但不需要反映更改在创建它的原始作用域中(例如,创建一个累加器,但对 sum 的更改不需要更改创建作用域中的 sum 变量),那么您可以类似地插入它,但作为静态变量:
There are some special cases where you can do it.
If you need to capture a variable by value (not by reference), and the value is a simple value type like a number, string, or array of the above (not reference types like objects and resources and functions), then you can simply insert it into the function definition using
var_export()
:If you need to capture the variable by reference in order to maintain mutable state across calls of the function, but you don't need to have the changes reflected in the original scope where it's created (e.g. to create an accumulator, but the changes to the sum don't need to change the sum variable in the creating scope), then you can similarly insert it, but as a static variable: