PHP、闭包和提取参数

PHP、闭包和提取参数,php,closures,anonymous-function,Php,Closures,Anonymous Function,我不知道如何最好的标题,所以我想我会张贴一个例子,我正在努力实现。我现在已经超级简化了这个 第一个是做动作的最基本的类 abstract class AuditedSave extends AuditedSaveImplementation { public static function run($callback = null) { return new AuditedSaveImplementation($callback); } } clas

我不知道如何最好的标题,所以我想我会张贴一个例子,我正在努力实现。我现在已经超级简化了这个

第一个是做动作的最基本的类

abstract class AuditedSave extends AuditedSaveImplementation
{

    public static function run($callback = null)
    {
        return new AuditedSaveImplementation($callback);
    }

}

class AuditedSaveImplementation
{

    public function __construct(Closure $closure)
    {
        echo ' - I ran before'; // point 1, $test = 0
        $closure();
        echo ' - i ran after!'; // point 2, $test = 1
    }

}
然后是调用它的代码

$test = 0;

AuditedSave::run(function() use ($test)
{
    $test = 1;
});
因此,在注释的第1点和第2点之间,闭包运行并将$test的值设置为1。但是,我想将作为第一个参数传递的任何值(在本例中,
$test
)存储为函数调用时的值的副本-该副本将始终运行,然后闭包会修改它(这是可以可变的部分),然后,进行比较,并根据差异采取行动——这将一直持续下去

但是,为了做到这一点,我需要能够访问
AuditedSaveImplementation
\uu construct()
方法中的$test变量,而不知道它的名称

这可能吗?

您可以使用class
getStaticVariables
方法通过
use
将参数传递给closure。像这样:

class AuditedSaveImplementation
{

    public function __construct(Closure $closure)
    {
        echo ' - I ran before'; // point 1, $test = 0
        $closureReflection = new ReflectionFunction($closure);
        $variables = $closureReflection->getStaticVariables();
        var_dump($variables);
        $closure();
        echo ' - i ran after!'; // point 2, $test = 1
    }

}
但如评论中所述,您应该重新思考如何做到这一点。 这不是一个好办法。尝试创建注释中建议的特殊类。

您可以使用class
getStaticVariables
方法通过
use
将参数传递给closure。像这样:

class AuditedSaveImplementation
{

    public function __construct(Closure $closure)
    {
        echo ' - I ran before'; // point 1, $test = 0
        $closureReflection = new ReflectionFunction($closure);
        $variables = $closureReflection->getStaticVariables();
        var_dump($variables);
        $closure();
        echo ' - i ran after!'; // point 2, $test = 1
    }

}
但如评论中所述,您应该重新思考如何做到这一点。
这不是一个好办法。尝试创建注释中建议的特殊类。

否,
$test
的范围与
AuditedSaveImplementation::\u construct
完全不同。你必须重新思考你想在这里做什么,这是不可能的。使用适当的逻辑(例如
getValue()
和/或
getOriginalValue()
)传入另一个类,而不是简单的闭包。另外,
$test
总是被复制到您指定的代码中(实际上它是写时复制的,但这不是很相关)。更改它不会影响原始变量。不,
$test
的范围与
AuditedSaveImplementation::\u construct
完全不同。你必须重新思考你想在这里做什么,这是不可能的。使用适当的逻辑(例如
getValue()
和/或
getOriginalValue()
)传入另一个类,而不是简单的闭包。另外,
$test
总是被复制到您指定的代码中(实际上它是写时复制的,但这不是很相关)。更改它不会影响原始变量。FWIW,这是一个糟糕的解决方案。要做到这一点,应该有一个合理而简单的接口,而不是一个依赖于实现细节的折衷解决方案。OP只是在错误的轨道上…我只是想表明这不是不可能的。通过
use
传递给闭包的所有内容都将转换为闭包的静态变量,并可通过反射提取。但我同意作者需要重新思考他在这里做什么。FWIW,这是一个糟糕的解决方案。要做到这一点,应该有一个合理而简单的接口,而不是一个依赖于实现细节的折衷解决方案。OP只是在错误的轨道上…我只是想表明这不是不可能的。通过
use
传递给闭包的所有内容都将转换为闭包的静态变量,并可通过反射提取。但我同意作者需要重新思考他在这里做什么。