Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created August 16, 2016 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindplay-dk/b7a4f154550067821666f777c5883503 to your computer and use it in GitHub Desktop.
Save mindplay-dk/b7a4f154550067821666f777c5883503 to your computer and use it in GitHub Desktop.
An ultra-naiive universal middleware host
<?php
// an ultra-simple middleware host that works for middleware callables with any signature.
// the last argument is always the `$next` function, which delegates to the next middleware.
class Host
{
/**
* @var callable[]
*/
private $stack;
/**
* @param callable[] $stack
*/
public function __construct(array $stack)
{
$this->stack = $stack;
}
/**
* Dispatch the middleware stack
*
* @return mixed
*/
public function __invoke()
{
$args = func_get_args();
return call_user_func_array($this->delegate(0), $args);
}
/**
* @param int $index
*
* @return callable
*/
protected function delegate($index)
{
if (isset($this->stack[$index])) {
return function() use ($index) {
$args = func_get_args();
$args[] = $this->delegate($index + 1);
return call_user_func_array($this->stack[$index], $args);
};
}
return function() {
throw new RuntimeException("middleware stack exhausted");
};
}
}
// example with request only:
$host = new Host([
function ($request, $next) {
return $next($request);
},
function ($request, $next) {
return "response({$request})";
}
]);
echo $host("request"); // => "response(request)"
echo "\n\n";
// example with request and response:
$host = new Host([
function ($request, $response, $next) {
return $next($request, $response);
},
function ($request, $response, $next) {
return "handled({$request}, {$response})";
}
]);
echo $host("request", "response"); // => "handled(request, response)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment