I am building an app using Front Controller design pattern and there is just one page index.php
through which all user requests pass as parameters (versus different pages/controllers in regular design).
How can I connect these parameters to application logic?
e.g. I have two different actions:
index.php?action=userLogin&username=admin&password=qwerty //process user login
index.php?action=displayUsersTable //show registered users
Currently I have an array
with all actions the system accepts (along with expected arguments) and I compare action
param from URL to the key
of this array and then check the required arguments for this action.
//1 = optional, 2=required
$systemActions = [
"userLogin" => [
"login" => 2,
"password" => 2
],
"displayUsersTable" => []
];
Obviously this going to become a monster array as the system grows.
Is there better approach to bind parameters sent to front controller to system actions?
As the code is "fixed" (i.e. not driven from a database) then there is no need to pump into an array (and all the processing/memory overhead that it requires. So yes, it can be improved.
But there are many options depending on how much the project will grow.
Simplest
The simplest would be simple "if" statements, or a switch. I'd start there to keep it simple.
More Complex
You say other projects have different pages / controllers - but there is a reason. And as you're asking for improvements, especially if you're expecting the project to grow to such as extent that you're looking for optimizations, then you really should consider these reasons (and split into files).
At the other end of the scale, you can split all the calls into files/classes and auto-load the files/classes.
This way you only execute the code you need (smaller file sizes), is very modular and easy to work on collaboratively. And if you add a new action, you don't need to modify the index or array - you only modify the action file you're working on.
Example (vastly simplified from a project I'm currently working on with this approach):
1) Create a "baseAction" base class the all actions will extend from. You can add common features such as cleaning/pre-processing parameters, logging, validating headers etc.
abstract class baseAction {
protected $aExpectedParams = [];
protected $aParams = [];
protected $validParams = true;
function __construct() {
foreach (self::$aExpectedParams as $name=>$aParam) {
if (isset($_GET[$name]))
if ($aParam['type'] == 'string') {
self::$aParams[$name] = $_GET[$name];
} elseif ($aParam['type'] == 'int') {
self::$aParams[$name] = (int)$_GET[$name];
}
} elseif ($aParam['required']) {
self::$validParams = false;
}
}
}
// This is the called function
abstract function execute();
}
2) Create the "action" classes, by extending the base Action. Save these in individual files (so others can collaborate on the project without interfering).
// put in 'actions/userLogin.php
class userLogin extends baseAction {
protected $aExpectedParams = [
'login' => ['type' => 'string', 'required' => true]
'password' => ['type' => 'string', 'required' => true] // NOTE: you should never actually pass password unencrypted through "get" as they'll get stuck in user logs!
];
public function execute() {
// Do Whatever
}
}
.
// put in 'actions/displayUsersTable.php
class displayUsersTable extends baseAction {
public function execute() {
// Do Whatever
}
}
3) Create an autoloader to pull in those individual files.
function myAutoloader($className) {
if (file_exists(__DIR__ . '/actions/' . $className . '.php')) {
require_once(__DIR__ . '/actions/' . $className . '.php');
}
}
spl_autoload_register ('myAutoloader');
4) Then your index.php is as clean as
$action = $_GET['action'] ?? '';
if (strlen($action) > 0 && class_exists($action) && method_exists($action, 'execute')) {
$oAction = new $action();
$oAction->execute();
} else {
// Oopsie
}
(Notes on this last snippet: the "class_exists" triggers the auto-loader. the "method_exists" is to check someone hasn't requested a common php class such as "object"; if you're being safer you should namespace this or add extra validation. This is just an example!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With