0

有没有办法否定回调的结果?

$this->myInjectedService->doSomething([$this, 'myCallback']);

我需要 nagate myCallback方法的结果。我知道我可以通过嵌套函数来做到这一点,但是有没有更干净的方法(感叹号)?

$this->myInjectedService->doSomething(function() {
    return !$this->myCallback();
});
4

1 回答 1

0

不,没有直接的方法可以做到这一点。

您可以做的是创建一个回调包装器,该包装器否定您要调用的回调。每次您想否定回调时,您都可以使用该包装器而不是回调本身:

<?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:即使可能,我也不建议使用这种方法,因为使用嵌套函数,就像你已经做过的那样,更清晰,更容易阅读/理解。

于 2020-03-31T09:09:02.477 回答