PHP中的参数闭包?(咖喱)

PHP中的参数闭包?(咖喱),php,parameters,closures,Php,Parameters,Closures,我似乎还记得,实际上有这种玩具,但我不确定。我几乎可以肯定PHP不会,我正在寻找一种方法来模拟它 假设我有几个闭包: $c1 = function($p) use ($obj) { return f($p, $obj, CONSTANT1); }; $c2 = function($p) use ($obj) { return f($p, $obj, CONSTANT2); }; $c3 = function($p) use ($obj) { return f($p, $obj, CONSTANT

我似乎还记得,实际上有这种玩具,但我不确定。我几乎可以肯定PHP不会,我正在寻找一种方法来模拟它

假设我有几个闭包:

$c1 = function($p) use ($obj) { return f($p, $obj, CONSTANT1); };
$c2 = function($p) use ($obj) { return f($p, $obj, CONSTANT2); };
$c3 = function($p) use ($obj) { return f($p, $obj, CONSTANT3); };
...
dostuff($somedata, $c1);
dostuff($somedata, $c2);
dostuff($somedata, $c3);
正如您所看到的,闭包代码的不同之处在于所使用的常量,我只想声明一个闭包并将其参数化。仅供参考,
CONSTANT1
CONSTANT2
CONSTANT3
不在
dostuff
范围内,我不想更改
dostuff
函数参数(因为它是公共接口的一部分),因此我不能将
CONSTANT*
直接传递到
dostuff
(顺便说一句,
dostuff
没有理由接受另一个函数的参数,只是把它们交给它:
dostuff
不能被迫知道除了
dostuff
本身必须提供的以外,闭包还需要什么)

我正在寻找一种方法,只编写clousure代码一次,并为其传递一个占位符值。然后,PHP应在闭包使用时,而不是在闭包调用时,将闭包代码中出现的占位符替换为指定值。这类似于动态闭包代码生成。例如:

/* beware, this is not PHP and it does not work */

$c = function($p) use ($obj) placeholder ($ph) { return f($p, $obj, $ph); };
...
dostuff($somedata, $c{CONSTANT1});
dostuff($somedata, $c{CONSTANT2});
dostuff($somedata, $c{CONSTANT3});

请注意,占位符语法是我自己编的,它只是为了澄清我的问题:我希望它能成功完成它的任务…

现在这里有一个可能的解决方案,但我没有把它包括在我的问题中,因为:

  • 这是一个答案
  • 它丑得出奇
  • 我想知道是否有更干净的方法
  • 我甚至不确定它是否真的有效
话虽如此,这就是我想出的怪物:

$constant = null;
$c = function($p) use ($obj, &$constant) { return f($p, $obj, $constant); };
...
$constant = CONSTANT1;
dostuff($somedata, $c);
$constant = CONSTANT2;
dostuff($somedata, $c);
$constant = CONSTANT3;
dostuff($somedata, $c);

您可以将闭包
$c
转换为一个函子,然后注入其依赖项,如下所示:

class C
{
    private $obj;
    private $constant;
    private $f;

    public function __construct($obj, $constant, $f)
    { 
        $this->obj = $obj;
        $this->constant = $constant;
        $this->f = $f;
    }

    public function __invoke($p)
    {
        return call_user_func_array($this->f, [
            $p, 
            $obj, 
            $constant
        ]);
    }
}

doStuff($somedata, new C($obj, CONSTANT1, $f));
doStuff($somedata, new C($obj, CONSTANT2, $f));
doStuff($somedata, new C($obj, CONSTANT3, $f));

考虑到常量是常量(在声明和执行时,值将是相同的)和全局的(没有范围问题),这可能是一个非常糟糕的示例…:)您是对的,但关键是
dostuff
没有理由使用这些常量,因为它们与dostuff的功能无关。我不知道用英语怎么说。。。我可以在我的问题中复制这个评论吗?做你想做的事。:)除了匿名类只存在于PHP7中,我猜它们不能用于此(因为您将被迫重写匿名类3次),而且像您这样的命名类击败了闭包的pourpose(具有匿名函数)的一部分。不过非常感谢你的回答,尽管如此,它还是非常有用。我还不明白这一点,但是,如果它能起作用,那绝对是棒极了。谢谢高级职能。接受函数作为参数和/或返回函数的函数。你甚至可以称之为穷人的咖喱。要查找的关键字很多。:)对“咖喱”,那是我在学校学习时他们认为我的关键词!如果可以的话,我会编辑我的评论,但似乎5分钟后,你犯的任何语法错误都会留给后代。所以是的,当我在学校的时候,他们也教我英语,我认为学习不规则动词很好。。。相反,今天我更倾向于相信,如果这种错误在我的余生中出现,那么像教育和思考这样的事情会给我留下更好的印象。。。我知道,我在这里离题了,如果有机会的话,我应该把这篇文章发到meta上。而且很可能这个评论包含了更多的语法错误,这些错误将永远存在……@LucioCrusca我实际上粗略地得出了相反的结论,更多的单词应该以“应该”结尾。对我来说更好
$c = function ($const) use ($obj) {
    return function ($p) use ($const, $obj) {
        return f($p, $obj, $const);
    };
};

doStuff($somedata, $c(CONSTANT1));