php Funktion aus anderer Klasse includen

Wie wäre es mit folgender Variante?
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:
ok da müsste ich mal schauen wie ich das ganze in mein Ordnesystem einbaue.
Das mit den Traits scheint mir am einfachsten zu sein
 
Nur weil es im ersten Moment einfacher aussieht, heißt es nicht, dass es auch sinnvoll ist. Du musst immer bedenken, dass das System so sein sollte, dass man es leicht erweitern kann, ohne dass man das ganze System umschreiben musst. In meinem Beispiel musst Du einfach nur den Dispatcher ändern und der Rest kann bleiben wie er will.
 
ok ja leuchtet ein.
Könntest du mir evtl helfen wie ich das ganze bei mir einbinde ?
Entweder ich stehe gewaltig auf dem schlauch oder ich blicks einfach nicht
 
Im Anhang ist die Ordner/Datei Struktur von meinem Projekt.
Wenn du Code brauchst lasse ich dir gerne zukommen
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    106,9 KB · Aufrufe: 12
Ich gehe mal davon aus, dass Deine ganzen Anfragen über die index.php geleitet werden. Insofern wäre die triviale Lösung, dass Du in Deiner index.php folgendes stehen hast:
PHP:
$dispatcher = new Dispatcher( $_REQUEST ); # das Request ist nur beispielhaft hier, sollte durch etwas anderes ersetzt werden
try {
  $dispatcher->controller( $_GET[ 'controller' ] )->action( $_GET[ 'action' ] );
} catch ( ActionNotFound $e ) {
  # Seite wurde nicht gefunden
   $dispatcher->controller( 'error' )->action( 'show' );
} catch ( ControllerNotFound $e ) {
  # Seite nicht gefunden
   $dispatcher->controller( 'error' )->action( 'show' );
}
Und dann kannst Du die Controller und Actions so aufrufen: index.php?controller=start&action=show
 
Nur die Klassen, die ich oben definiert habe. Aber ansonsten kannst Du das so in Deine index.php übernehmen.
 
Also quasi folgendes in eine eigene Datei
PHP:
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();
 }
}

und dann die Klasse includen und "verwenden" ??

Nun stellt sich jedoch das Problem das meine index.php wo alles "verarbeitet" wird so aussieht:

PHP:
<?php 
    require('config.php');

    $url = (isset($_GET['url'])) ? $_GET['url'] : "index/index";
    $url = explode("/", $url);

    if(isset($url[0])){$controller = $url[0];}
    if(isset($url[1])) { if($url[1] != "") {$method = $url[1];}}
    if(isset($url[2])) { if($url[2] != "")  {$params = $url[2];}}

    spl_autoload_register(function($class){
        if(file_exists(LIBS.$class.".php")){
            require LIBS.$class.".php";
        }
    });

    $path = './controllers/'.$controller.".php";

    if(file_exists($path)){
        require $path;
        $controller = new $controller();

        if(isset($method)){
                if(method_exists($controller, $method)){
                    if(isset($params)){

                        $controller->{$method}($params);

                    } else {
                        $controller->{$method}();
                    }
                } else {
                    $controller->index();
                }
            }
        } else {
            echo "Controller Not Found";
        }

    ?>

Meine Links sehen z.b so aus domain/index/index
 

Neue Beiträge

Zurück