Created
December 20, 2015 21:06
-
-
Save jm42/766e1c30546569553e04 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
| namespace App; | |
| use App\Config\Configurator; | |
| use App\HTTP\Request; | |
| class App { | |
| private $name; | |
| private $config; | |
| function __construct($name, Configurator $config) { | |
| $this->name = $name; | |
| $this->config = $config; | |
| } | |
| function __invoke(Request $req) { | |
| foreach ($this->config->resolve() as $key => $fn) { | |
| call_user_func($fn); | |
| } | |
| } | |
| function getPath() { | |
| return basename(__DIR__); | |
| } | |
| function match($method, $regexp, callable $handler) { | |
| $connect = function() use($method, $regexp, $handler) { | |
| // TODO | |
| }; | |
| $this->config->insert($this->getPath(), "$method+$regexp", $connect); | |
| } | |
| protected function configure(Container $container) { | |
| $container['app.debug'] = true; | |
| } | |
| protected function register() { | |
| return [ | |
| new UserModule($this->config), | |
| ]; | |
| } | |
| } |
This file contains hidden or 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 | |
| namespace App\Config; | |
| class ConflictException extends \Exception {} | |
| class Configurator extends \SplPriorityQueue { | |
| private $order = PHP_INT_MAX; | |
| function insert($path, $key, $value, $priority=0) { | |
| parent::insert([$key, $value], [$priority, $path, --$this->order]); | |
| } | |
| function resolve() { | |
| $grouped = []; | |
| $conflicts = []; | |
| $this->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); | |
| foreach ($this as $value) { | |
| $key = $value['data'][0]; | |
| if (isset($grouped[$key])) | |
| $grouped[$key][] = $value; | |
| else | |
| $grouped[$key] = [$value]; | |
| } | |
| foreach ($grouped as $key => $values) { | |
| $base = array_shift($values); | |
| $path = $base['priority'][1]; | |
| $plen = strlen($path); | |
| foreach ($values as $value) { | |
| $curr = $value['priority'][1]; | |
| $clen = strlen($curr); | |
| if ( | |
| strncasecmp($curr, $path, $plen) >= 0 || | |
| substr($path, 0, $clen) !== $curr | |
| ) { | |
| if (isset($conflicts[$key])) | |
| $conflicts[$key][] = $value; | |
| else | |
| $conflicts[$key] = [$base, $value]; | |
| } | |
| } | |
| yield $base['data'][0] => $base['data'][1]; | |
| } | |
| if ($conflicts) { | |
| throw new ConflictException; | |
| } | |
| } | |
| function merge(self $config, $prefix=null) { | |
| $copy = clone $config; | |
| $copy->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); | |
| foreach ($copy as $value) { | |
| $data = $value['data']; | |
| $priority = $value['priority']; | |
| $this->insert($priority[1], $data[0], $data[1], $priority[0]); | |
| } | |
| } | |
| } |
This file contains hidden or 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 | |
| namespace App\HTTP; | |
| class Message { | |
| private $headers; | |
| private $body; | |
| function __construct(array $headers=[], $body=null) { | |
| $this->headers = $headers; | |
| if ( | |
| is_null($body) || ( | |
| gettype($body) === 'resource' && | |
| get_resource_type($body) === 'stream' | |
| ) | |
| ) { | |
| $this->body = $body; | |
| } else { | |
| $this->body = fopen('php://temp', 'r+'); | |
| fwrite($this->body, $body); | |
| rewind($this->body); | |
| } | |
| } | |
| function hasHeader($header) { | |
| return isset($this->headers[$header]); | |
| } | |
| function getHeader($header) { | |
| $header = strtolower($header); | |
| $headers = array_change_key_case($this->headers, CASE_LOWER); | |
| if (array_key_exists($header, $headers)) { | |
| return is_array($headers[$header]) | |
| ? implode(', ', $headers[$header]) | |
| : $headers[$header]; | |
| } | |
| } | |
| function getHeaders() { | |
| return array_keys($this->headers); | |
| } | |
| function getBody() { | |
| return $this->body; | |
| } | |
| } | |
| class Request extends Message { | |
| private $method; | |
| private $target; | |
| function __construct($method, $target, array $headers=[], $body=null) { | |
| $this->method = strtoupper($method); | |
| $this->target = strtolower($target); | |
| parent::__construct($headers, $body); | |
| } | |
| function getMethod() { | |
| return $this->method; | |
| } | |
| function getTarget() { | |
| return $this->target; | |
| } | |
| } | |
| class Response extends Message { | |
| private $statusCode; | |
| private $reasonPhrase; | |
| private static $phrases = [ | |
| 200 => 'OK', | |
| ]; | |
| function __construct($statusCode=200, array $headers=[], $body=null) { | |
| $this->statusCode = $statusCode; | |
| $this->reasonPhrase = isset(static::$phrases[$this->statusCode]) | |
| ? static::$phrases[$this->statusCode] : null; | |
| parent::__construct($headers, $body); | |
| } | |
| function getStatusCode() { | |
| return $this->statusCode; | |
| } | |
| function getReasonPhrase() { | |
| return $this->reasonPhrase; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment