是否有可能模拟在PHP 5.2.x闭包不使用全局? [英] Is it possible to simulate closures in PHP 5.2.x not using globals?

查看:96
本文介绍了是否有可能模拟在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.

任何想法?

推荐答案

有趣的问题。我会说这是不可能的,但让我们看看

Interesting question. I'd say it's not possible at all, but let's see

引用 IBM - PHP5.3,第2部分的新功能


闭包是一个在自己的环境中进行计算的函数,它有一个或多个绑定变量,当函数被调用时可以访问。

A closure is a function that is evaluated in its own environment, which has one or more bound variables that can be accessed when the function is called.

并进一步(强调我)


要导入的变量从封闭函数定义的use子句中指定。默认情况下,它们通过值传递,这意味着如果我们更新在闭包函数定义中传递的值,它将不会更新外部值。

Variables to be imported from the outside environment are specified in the use clause of the closure function definition. By default, they are passed by value, meaning that if we would update the value passed within the closure function definition, it would not update the outside value.

使用全局将通过引用传递,尽管可以绑定变量通过使用& 使用子句中的闭包引用,它已经是5.3默认行为的偏差。

Using global would pass by reference and although it is possible to bind variables by reference with a closure by using & in the use clause, it is already a deviation from the 5.3 default behavior.

$var = 'yes';
$fn  = create_function('', 'global $var; $var = "no";');
$fn();
echo $var; // outputs no

您可以复制全局变量以便按值使用,例如

You could copy the global variable in order to use it by value though, e.g.

$var = 'yes';
$fn  = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
$fn();
echo $var; // outputs yes

此外,全局变量的值(当使用 create_function )将不会被评估(绑定)。

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 run

$var = 'yes';
$fn  = create_function('', 'global $var; $tmp = $var; return $tmp;');
$var = 'maybe';
echo $fn(); // outputs maybe

$var = 'yes';
$fn  = function() use ($var) { return $var; };
$var = 'maybe';
echo $fn(); // outputs yes

也很重要的是


当在一个对象中定义时,一个方便的事情是,闭包通过$ this变量完全访问对象,而不需要显式导入。 *虽然我认为这是在最后PHP5.3中删除

$ c> global 关键字,你也不能使用 $ this 。在用 create_function 定义函数体时,没有办法从类中引用属性。

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 with create_function.

class A {

    protected $prop = 'it works';

    public function test()
    {
        $fn = create_function('', 'echo $this->prop;');
        return $fn;
    }
}

$a = new A;
$fn = $a->test();
$fn();

会导致

Fatal error: Using $this when not in object context

总结此

虽然可以创建从全局范围导入变量的函数,但是不能使用另一个范围的变量创建一个变量。并且因为你在使用 create_function 时在技术上没有绑定,但是在创建的函数执行时导入,我想争论这个限制使闭包成为lambda

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.

编辑:下面的Onno Marsman提供的解决方案是相当不错的。它不完全模拟Closures,但实现是相当接近。

The solution offered by Onno Marsman below is pretty decent though. It doesn't fully simulate Closures, but the implementation is pretty close.

这篇关于是否有可能模拟在PHP 5.2.x闭包不使用全局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆