Created
August 16, 2016 12:52
-
-
Save mindplay-dk/b7a4f154550067821666f777c5883503 to your computer and use it in GitHub Desktop.
An ultra-naiive universal middleware host
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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