Is there any way to negate result of callback?
$this->myInjectedService->doSomething([$this, 'myCallback']);
I need to nagate result of myCallback method. I know I can do it by nested function, but is there any more clean way (exclamation mark)?
$this->myInjectedService->doSomething(function() {
return !$this->myCallback();
});
No, there is no direct way to do it like that.
What you could do, would be to create a callback wrapper which negates the callback you want to call. Every time you want to negate a callback you can use that wrapper instead of the callback itself:
<?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();
The results would be:
// Scenario 1
bool(true)
// Scenario 2
bool(true)
// Scenario 3
bool(false)
Please note that this is the simplest approach I could think of, but if you need more complex callbacks to be called then you might need to update the wrapper.
PS: Even if it's possible, I don't recommend using this approach, as using a nested function, as you already did, is much more clear and easier to read/understand.