Parantatatam
mag Cookies & Kekse
Wie wäre es mit folgender Variante?
Nachtrag: Man kann es auch noch so erweitern:
PHP:
class PageController {
public function action( $action_name ) {
$method_name = 'action_' . $action_name;
if ( !method_exists( $this, $method_name ) ) {
throw new Exception( "action {$action_name} does not exist" );
}
$this->$method_name();
}
}
class Dispatcher {
public function controller( $controller_name ) {
$class_name = $controller_name . 'Controller';
if ( !class_exists( $class_name ) || !is_subclass_of( $class_name, 'PageController' ) ) {
throw new Exception( "controller {$class_name} does not exist" );
}
return new $class_name();
}
}
class NewsController extends PageController {
public function action_index() {
echo "news#index";
}
}
class StartController extends PageController {
public function action_index() {
$dispatcher = new Dispatcher();
$dispatcher->controller( 'news' )->action( 'index' );
}
}
$dispatcher = new Dispatcher();
$dispatcher->controller( 'start' )->action( 'index' );
Nachtrag: Man kann es auch noch so erweitern:
PHP:
# Exception für nicht gefundene Action-Methoden
class ActionNotFound extends Exception {
public function __construct( $action_name ) {
parent::__construct( "action {$action_name} not found" );
}
}
# Exception für nicht gefundene Controller-Klassen
class ControllerNotFound extends Exception {
public function __construct( $controller_name ) {
parent::__construct( "controller {$controller_name} not found" );
}
}
class PageController {
private $env; # gemeinsam geteilte Umgebungsvariable
public function __construct( &$env ) {
$this->env =& $env; # Umgebungsvariable mit Referenz (!) speichern
}
public function action( $action_name ) {
# Methodennamen für Action erstellen
$method_name = 'action_' . $action_name;
if ( !method_exists( $this, $method_name ) ) {
throw new ActionNotFound( $action_name );
}
# Action aufrufen
$this->$method_name();
}
# rendert eine andere Action ($opts deshalb, weil die Methode umfangreicher sein kann)
protected function render( $opts ) {
if ( is_string( $opts ) {
if ( strstr( $opts, '#' ) !== false ) {
# ermittel Controllernamen und Actionnamen
list( $controller_name, $action_name ) = explode( '#', $opts, 2 );
# erstelle Dispatcher und übergebe Umgebungsvariable
$dispatcher = new Dispatcher( $this->env );
# rufe Action in Controller auf
return $dispatcher->controller( $controller_name )->action( $action_name );
}
}
}
}
class Dispatcher {
private $env;
public function __construct( &$env ) {
$this->env =& $env;
}
public function controller( $controller_name ) {
$class_name = $controller_name . 'Controller';
if ( !class_exists( $class_name ) || !is_subclass_of( $class_name, 'PageController' ) ) {
throw new ControllerNotFound( $controller_name );
}
return new $class_name( $this->env );
}
}
class StartController extends PageController {
public function action_index() {
$this->render( 'news#index' ); # {controller}#{action}
}
}
try {
$dispatcher = new Dispatcher( $_REQUEST );
$dispatcher->controller( 'start' )->action( 'index' );
# Controller nicht gefunden
} catch ( ControllerNotFound $e ) {
trigger_error( $e->getMessage(), E_USER_ERROR );
# Action nicht gefunden
} catch ( ActionNotFound $e ) {
trigger_error( $e->getMessage(), E_USER_ERROR );
}
Zuletzt bearbeitet: