Skip to content

Instantly share code, notes, and snippets.

@jm42
Created December 20, 2015 21:06
Show Gist options
  • Save jm42/766e1c30546569553e04 to your computer and use it in GitHub Desktop.
Save jm42/766e1c30546569553e04 to your computer and use it in GitHub Desktop.
<?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),
];
}
}
<?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]);
}
}
}
<?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