Skip to content

Instantly share code, notes, and snippets.

@munro
Created February 21, 2012 20:08
Show Gist options
  • Save munro/1878573 to your computer and use it in GitHub Desktop.
Save munro/1878573 to your computer and use it in GitHub Desktop.
PHP Class-Based Views
<?php
class Http404 extends Exception {
}
class Builder {
private $callback, $args, $kwargs;
public function __construct($callback, $args = array(), $kwargs = array()) {
$this->callback = $callback;
$this->args = $args;
$this->kwargs = $kwargs;
}
public function __invoke() {
return call_user_func(
$this->callback,
$this->args,
func_get_args(),
$this->kwargs
);
}
public function __call($name, $args) {
if (count($args) === 1) {
$args = $args[0];
}
return new Builder(
$this->callback,
$this->args,
array_merge($this->kwargs, array($name => $args))
);
}
}
class View {
public function __construct($args, $kwargs) {
$this->args = $args;
$this->kwargs = $kwargs;
foreach ($this->kwargs as $key => &$value) {
$this->{$key} = $value;
}
}
public function get() {
//throw new Http404();
echo "Getting...\n";
}
public function post() {
return call_user_func_array(array($this, 'static::get'), func_get_args());
}
public function dispatch() {
echo "Dispatched!\n";
}
static public function asView() {
$cls = new ReflectionClass(get_called_class());
return new Builder(function ($init_args, $call_args, $kwargs) use ($cls) {
return $cls->getMethod('dispatch')->invokeArgs(
$cls->newInstance($init_args, $kwargs),
$call_args
);
}, func_get_args());
}
}
class ListView extends View {
}
class MyView extends ListView {
public function dispatch($rwar) {
echo "My View: " . implode(func_get_args(), ', ') . "\n";
$this->post();
parent::dispatch();
}
}
$fn = MyView::asView()->template('hello/world.html');
$fn2 = $fn->helloWorld('rwar rwar');
$fn('hello', 'view');
$fn2('foo', 'bar');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment