Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.
Popular code excerpts may be moved to "Code Snippets" by the moderators.
<?php
require_once 'C:\wamp\www\core\classes\Request.inc.php';
// COMMANDS
class Front_Command{
protected $action;
public function execute(){
echo "Error: Could not find specified command";
}
public function doExecute( Front_Command $command ){
$command->execute();
}
}
class Front_Command_default extends Front_Command{
public function __construct(){
$this->action = "Default";
}
public function execute(){
echo $this->action . " was executed.";
}
}
class Front_Command_login extends Front_Command{
public function __construct(){
$this->action = "Login";
}
public function execute(){
echo $this->action . " was executed.";
}
}
// ENDCOMMANDS
// Request is just a class that gets request info (from url, forms, command line, etc.)
// Front request is specialized in that it returns information specific to the front controller
class Front_Request extends Request{
protected $default;
protected $error;
public function __construct($default, $error){
parent::__construct();
$this->default = $default;
$this->error = $error;
}
public function getCommand(){
return $this->action ? $this->action : $this->default;
}
public function getCommandDefault(){
return $this->default;
}
public function getCommandError(){
return $this->error;
}
}
class Front_Command_Resolver{
public function getCommandComponent( Front_Request $request ){
// Get command from request object
$command = $request->getCommand();
// Assign class name with command appended
$class_name = "Front_Command_{$command}";
// If this specific class exists, return it
if(class_exists($class_name)){
return new $class_name();
}
// Otherwise return the standard command
return new Front_Command();
}
}
class Front_Controller{
private static $instance = null;
private function __construct(){
// Some sort of initialization
}
public function getInstance(){
// This shouldn't need an explanation, but I'll explain anyway... it ensures that only one instance of this can be instantiated
if( ! self::$instance ) {
self::$instance = new Front_Controller();
}
return self::$instance;
}
public function run(){
// Get request from user (could be by url/command line... not up to this class to decide... left up to the front request object)
$request = new Front_Request('default', 'error');
// Get an instance of the command resolver
$command_resolver = new Front_Command_Resolver();
// Resolve the user's command into a command component (a descendant of our friend ^^ the Front_Command
$command = $command_resolver->getCommandComponent( $request );
// Execute the command
$command->execute();
}
}
$Controller = Front_Controller::getInstance();
$Controller->run();
?>
You are on your way. One note is that those Commands that are dispatched by your Front Controller are called "Actions" by most people. It is a convention that goes back to Struts and beyond. They are often named something like "LoginController" or "LoginAction".
The Ninja Space Goat wrote:So how can I modify this to send the action to the model/view?
You don't "send the action to the model/view", the Action is the Controller. It can create both the Model and the View -- passing the Model to the View, or the View can create the Model itself. But the Action takes over flow control once it is dispatched by the Front Controller.
<?php
abstract class Controller_Front_Action{
protected $action;
//protected $view; <-- this is just something I'm thinking about right now... see any problem with this methodology?
//protected $model; <-- Same with this
abstract public function execute();
}
?>
<?php
class Controller_Front_ActionResolver{
protected $action;
protected $path;
protected $ext;
public function __construct( Controller_Front_Request $request ){
// Get action from request object
$this->action = $request->getAction();
}
// Need to add autoloading functionality
public function getComponent( $prefix='', $suffix='Action', $ext='.php' ){
$path_name = $prefix . $this->action . $ext;
if(file_exists($path_name)){
require_once $path_name;
$class_name = $this->action . $suffix;
// If this specific class exists, return it
if(class_exists($class_name, false)){
return new $class_name();
}
}
// Otherwise return the error action
return new Front_Action_Error();
}
}
?>
<?php
class Controller_Front_Front{
private static $instance = null;
public function getInstance(){
// This shouldn't need an explanation, but I'll explain anyway... it ensures that only one instance of this can be instantiated
if( ! self::$instance ) {
self::$instance = new Controller_Front_Front();
}
return self::$instance;
}
public function run($path){
// Get request from user (could be by url/command line... not up to this class to decide... left up to the front request object)
$request = new Controller_Front_Request('login');
// Get an instance of the command resolver
$action_resolver = new Controller_Front_ActionResolver( $request );
// Resolve the users action into a command component (a descendant of our friend ^^ the Front_Action
$action = $action_resolver->getComponent( $path );
// Execute the action
$action->execute();
}
}
?>
<?php
// Request is just a class that gets request info (from url, forms, command line, etc.)
// Front request is specialized in that it returns information specific to the front controller
class Controller_Front_Request extends Request{
protected $default;
public function __construct($default){
parent::__construct();
$this->default = $default;
}
public function getAction(){
return $this->action ? $this->action : $this->default;
}
public function getActionDefault(){
return $this->default;
}
}
?>