有没有办法否定回调的结果?
$this->myInjectedService->doSomething([$this, 'myCallback']);
我需要 nagate myCallback方法的结果。我知道我可以通过嵌套函数来做到这一点,但是有没有更干净的方法(感叹号)?
$this->myInjectedService->doSomething(function() {
return !$this->myCallback();
});
不,没有直接的方法可以做到这一点。
您可以做的是创建一个回调包装器,该包装器否定您要调用的回调。每次您想否定回调时,您都可以使用该包装器而不是回调本身:
<?php
class SomeService
{
public function doSomething(callable $callback)
{
return call_user_func($callback);
}
}
final class CallbackWrapper
{
public static function call(callable $callback, bool $negate = false): callable
{
if ($negate) {
return function() use ($callback) {
return !call_user_func($callback);
};
}
return $callback;
}
}
class Test
{
public function __construct()
{
$this->someService = new SomeService();
}
public function doSomething()
{
// Scenario 1: use direct callback
$result = $this->someService->doSomething([$this, 'thisIsACallback']);
var_dump($result);
// Scenario 2: use wrapper without negating
$result = $this->someService->doSomething(
call_user_func_array('CallbackWrapper::call', [[$this, 'thisIsACallback']])
);
var_dump($result);
// Scenario 3: use wrapper with negation
$result = $this->someService->doSomething(
call_user_func_array('CallbackWrapper::call', [[$this, 'thisIsACallback'], true])
);
var_dump($result);
}
public function thisIsACallback(): bool
{
return true;
}
}
$test = new Test();
$test->doSomething();
结果将是:
// Scenario 1
bool(true)
// Scenario 2
bool(true)
// Scenario 3
bool(false)
请注意,这是我能想到的最简单的方法,但是如果您需要调用更复杂的回调,那么您可能需要更新包装器。
PS:即使可能,我也不建议使用这种方法,因为使用嵌套函数,就像你已经做过的那样,更清晰,更容易阅读/理解。