PHP - nagate 回调结果

PHP - nagate callback result

有什么方法可以否定回调的结果吗?

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