name = $name; $this->attributes = $attr; $this->value = $value; } public function __toString() { $ret = '<'. $this->name; if (!empty($this->attributes)) { $ret .= ' ' . implode(' ', $this->attributes); } if (empty($this->value)) { $ret .= ' />'; } else { $ret .= '>'; if ($this->value instanceof Element) { $ret .= (string) $this->value; // force __toString() } elseif (is_array($this->value)) { $ret .= implode('', $this->value); } else { $ret .= $this->value; } $ret .= "name>"; } return $ret; } } class Context { /** * Directory in which the current script is located. * * Follow symlinks if applicable, to obtain the actual implementation * directory, instead of just the main file symlink, in order to find the * other files. * * @var string */ protected $dirname; /** * Requested path: <$PHP_SELF>?q=a/b/c * * @var string */ protected $path = NULL; /** * Graphics context * * @var GraphicsContext */ protected $gc = NULL; public function getDirname() { if (!isset($this->dirname)) { $this->dirname = dirname(__FILE__); } return $this->dirname; } /** * Return the requested path. * * @param string $path */ public function getPath() { if (!isset($this->path)) { $this->path = empty($_GET['q']) ? '' : $_GET['q']; } return $this->path; } /** * User information: logged or not ? * * @var boolean */ protected $user = FALSE; function __construct() { $this->getPath(); } function __toString() { $ret = '
' . print_r($this, TRUE) . '
'; return $ret; } } class Page extends Element { /** * @var Context */ protected $context; /** * @var array */ protected $styles; /** * @var array */ protected $finalized = array(); public function getHeader($name) { } public function setHeader($name, $value) { } public function getHead() { $this->finalizeHead(); $head = new Element('head', NULL, $this->head); $ret = (string) $head; return $ret; } public function setHead($item) { } public function getBody() { $this->finalizeBody(); $body = new Element('body', NULL, $this->body); $ret = (string) $body; return $ret; } public function setBody($fragment) { $this->body[] = $fragment; } public function finalizeHead() { if (isset($this->finalized['head'])) { throw new Exception('Attempt to finalize already finalized head'); } $cssLink = new Element('link', array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->context->getPath() .'/memcache_ui.css', )); $this->setHead($cssLink); $this->finalized['head'] = TRUE; } public function finalizeBody() { if (isset($this->finalized['body'])) { throw new Exception('Attempt to finalize already finalized body'); } $this->finalized['body'] = TRUE; } public function render() { $html = new Element('html', NULL, $this->getHead() . $this->getBody()); return (string) $html; } /** * Page constructor. * * @param Context $context * @param array $item * A router info array. * * @see Router::getInfo() */ public function __construct(Context $context, array $item) { parent::__construct('html'); $this->context = $context; } } class Router { function getInfo() { $ret = array( '^server/(\w+)/flush/(\w+)$' => array( 'page class' => 'page_server_flush', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_server', 'title arguments' => 'page arguments', ), '^server/(\w+)/flush$' => array( 'page class' => 'page_server_flush', 'page arguments' => array('$1'), 'title callback' => 'title_server', 'title arguments' => 'page arguments', ), '^server/(\w+)/slab/(\d+)$' => array( 'page class' => 'page_slab_view', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_slab', 'title arguments' => 'page arguments', ), '^server/(\w+)/key/(.+)/delete/(\w+)$' => array( 'page class' => 'page_variable_delete_confirm', 'page arguments' => array('$1', '$2', '$3'), 'title callback' => 'title_variable', 'title arguments' => 'page arguments', ), '^server/(\w+)/key/(.+)/delete$' => array( 'page class' => 'page_variable_delete_form', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_variable', 'title arguments' => 'page arguments', ), '^server/(\w+)/key/(.+)/dump$' => array( 'page class' => 'page_variable_view_php', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_variable', 'title arguments' => 'page arguments', ), '^server/(\w+)/key/(.+)/php$' => array( 'page class' => 'page_variable_view_php', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_variable', 'title arguments' => 'page arguments', ), '^server/(\w+)/key/(.+)$' => array( 'page class' => 'page_variable_view_text', 'page arguments' => array('$1', '$2'), 'title callback' => 'title_variable', 'title arguments' => 'page arguments', ), '^slabs$' => array( 'page class' => 'page_slab_overview', 'title' => 'Slabs per server', ), '^$' => array( 'page class' => 'Page_Main', 'title' => 'Overview', ), ); return $ret; } function getRoute() { $found = FALSE; $path = $this->context->getPath(); // echo "
Path: [". $path . "]

"; $matches = array(); foreach ($this->getInfo() as $regex => $info) { $regex = "@$regex@"; $count = preg_match($regex, $path, $matches); // echo "
$regex: $count";
      // if ($count) print_r($matches);
      // echo "
"; if ($count) { $found = TRUE; break; } } if ($found) { // echo "Found at $regex
";
      // print_r($info);
      $regexes = array_fill(0, count($info['page arguments']), $regex);
      $paths = array_fill(0, count($info['page arguments']), $path);
      $info['page arguments'] = preg_replace($regexes, $info['page arguments'], $paths);
    }
    else {
      $info = NULL;
    }

    return $info;
  }

  function __construct(Context $context) {
    $this->context = $context;
  }
}

class Page_Main extends Page {
  function finalizeBody() {
    $hello = new Element('p', NULL, 'Hello world');
    $this->setBody($hello);
    parent::finalizeBody();
  }

}

function main() {
  $context = new Context();
  // echo "

Dirname: [". $context->getDirname() . "]

"; // echo "

Path: [". $context->getPath() . "]

";

  $router = new Router($context);
  $item = $router->getRoute();
  $page = new $item['page class']($context, $item);
  // echo '
'; var_dump($page);
  echo $page->render();
}

try {
  main();
}
catch (Exception $e) {
  echo '
';
  echo $e->getMessage() . PHP_EOL;
  echo $e->getTraceAsString();
  echo "
"; }