TypedCallable
Abstract PHP class, which allows to implement callables with signature check, (*1)
Installation
composer require czt08883/typed-callable dev-master
Usage
Define your own class extending TypedCallable, (*2)
use Czt08883\TypedCallable\TypedCallable\TypedCallable;
class OnDataCallable extends TypedCallable
{
/**
* Implement "useTemplate()" abstract method.
* This method must return a callable, which will
* be used as a template for signature check.
*
* @return callable
*/
public function useTemplate()
{
return function(SomeClass $a, array $b, $c){};
}
}
In your other class, which requires typed callable:, (*3)
- store this typed callable as a property
-
invoke this typed callable on some event, passing some data, (*4)
class DataReceiverExample
{, (*5)
/**
* @var OnDataCallable
*/
private $onDataCallback;
/**
* Use this typed callable as an argument in some function
* to setup a callback
*/
public function setOnDataCallback(OnDataCallable $callback)
{
$this->onDataCallback = $callback;
}
/**
* Execute your callback on some event, passing proper parameters.
* For example, on receiving data from external source
*/
public function onData()
{
// ... receive some data and pass it to callback ...
call_user_func(
$this->onDataCallback,
[
new SomeClass,
['some','data','as','array'],
"some string"
]
);
}
}, (*6)
Use your DataReceiverExample, (*7)
$dataReceiver = new DataReceiverExample();
$dataReceiver->setOnDataCallback(
new OnDataCallable(
function (SomeClass $a, array $b, $c) {
// just display it, for example
echo "Yay, received some data.";
}
)
);
/* Simulate incoming data event:
* This will invoke a callback, installed earlier. So output will be
* "Yay, received some data."
*/
$dataReceiver->onData();
Now let us test callback with wrong signature.
Following code will trigger TypedCallableSignatureMismatchException
with following message:
"Callable signature mismatch. Callable must be: function(SomeClass $a, array $b, $c){...}", (*8)
$dataReceiver->setOnDataCallback(
new OnDataCallable(
function (SomeOtherClass $c) {
// ... other actions, not important here
}
)
);