1
\$\begingroup\$

This question is a sub-post to this question

This post is a follow up for this and this.

"In this particular question I need the reviewers help to judge my front controller design pattern"


.htaccess file

it's purpose is to internally redirect to the front controller file

RewriteEngine On
RewriteCond "%{REQUEST_URI}" "!=/frontController.SE.php"
RewriteCond %{REQUEST_FILENAME} !^.*\.js$
RewriteCond %{REQUEST_FILENAME} !^.*\.css$
RewriteCond %{REQUEST_FILENAME} !^.*\.ico$
RewriteCond %{REQUEST_URI} !^/media/.*$
RewriteRule .* /frontController.SE.php [L]

frontController.SE.php

The front controller will receive the request and decide 2 things :

  1. what is the action name intended by the request .
  2. which sub controller knows how to handle that action and then include it.

(I'm planing to expand the front controller functionalities later to do things like logging the requests, blocking requests,.. etc). the controllers files have names like "/name.SE.php" SE is for "side effects" since PSR stated that a php file must either has definitions or do side effects. the controllers files has functions inside it with names exactly the same name as the action name that the is requested.

<?php
namespace aap;

require_once 'classes/AutoLoader.class.php';
$autoLoader = new AutoLoader($_SERVER["DOCUMENT_ROOT"] . "classes/", "aap\\");
$autoLoader->register();

$sysModel = new SystemModel();
$frontController = new FrontController();

$subController = $frontController->getSubController();

if ($subController) {
    include $frontController->getSubControllerFile();
} else {
    die("bad Rrequest");
}

FrontController.class.php

<?php
namespace aap;

class FrontController
{

    protected $subController = "";

    protected $subControllerFile = "";

    protected $action = "";

    public function __construct()
    {
        $path = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), "/");
        $pathParts = explode("/", $path);

        switch ($pathParts[0]) {
            // name/home
            case "home":
            case "":
                $this->subController = "home";
                $this->subControllerFile = "home.SE.php";
                $this->action = "show";
                break;
            // name/about
            case "about":
                $this->subController = "about";
                $this->subControllerFile = "about.SE.php";
                $this->action = "show";
                break;
            // name/contact/send
            // name/contact
            case "contact":
                $this->subController = "contact";
                $this->subControllerFile = "contact.SE.php";
                if (! empty($pathParts[1]) && $pathParts[1] == "send" && $_SERVER['REQUEST_METHOD'] == "POST") {
                    $this->action = "send";
                } else {
                    $this->action = "show";
                }
                break;
            default:
                $this->subController = false;
                break;
        }
    }

    public function getSubController()
    {
        return $this->subController;
    }

    public function getSubControllerFile()
    {
        return $this->subControllerFile;
    }

    public function getAction()
    {
        return $this->action;
    }
}

contact.SE.php

a sub controller example (it's code is omitted)

<?php
namespace aap;
// contact.SE.php (a controller designed to be included by the fron controller)
/*
 * @actions list:
 * 1-show
 * 2-send
 */
switch ($frontController->getAction()) {
    case "send":
        send($sysModel);
        break;
    default:
        show($sysModel);
        break;
}

function show(SystemModel $sysModel){}
function send(SystemModel $sysModel){}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.