I have written a code for an application/website that I wanted to be structured similarly to MVC design pattern (but I think it's rather MVP based on comparison I read). This functions as a kind of intranet where users can log in, see some news, short info about them - all on one page (some of the content is static and some dynamic based on the user).
I structured my code in the following way:
- presentation pages (index.php, main.php, admin.php, error.php)
- all input is processed by JavaScript (jQuery) by
$.post
function which calls my router.php script passing name of a class & method to call and additional params to be passed to that method; this script processes the input and uses Controller.php class to handle that request - Controller class handles instantiating of the right class and calling its method and returning the results to presentation pages by using callbacks on $.post
- Controller calls specific methods in classes representing user, news etc.
Please mind the naming of my routher.php and Controller class - it's how I called them but this might not be correct from the MVC/MVP point of view - if so please point that out.
Questions that I have in my mind:
- Is this right structure?
- Should I combine code in router.php & Controller.php into one entity?
- How should JavaScript code be stored? At the moment I'm using one .js file for handling login included in index file and one for the rest of the presentation pages.
- I'm storing all info (User object, news etc.) in $_SESSION variable.
- Can I store connection details in global variable (I read a lot on Stack Overflow that this is discouraged/bad practice)?
Please comment, advise and share your opinion - all constructive criticism is welcome.
router.php:
<?php
require_once 'config.php';
require_once 'Controller.php';
ini_set("log_errors", 1);
ini_set("error_log", LOG_PATH . "Controller.log");
ini_set('display_errors', 0);
error_reporting(E_ALL);
startIntranetSession();
try
{
$appController = new Controller();
if (isset($_POST['params']))
{
if (sizeof($_POST['params']) > 1)
{
$method = filter_input(INPUT_POST, 'method', FILTER_SANITIZE_STRING);
$class = filter_input(INPUT_POST, 'class', FILTER_SANITIZE_STRING);
$params = filter_input(INPUT_POST, 'params', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
$methodToCall = $class . "::" . $method;
echo $appController->callMethod($methodToCall, $params);
}
elseif (sizeof($_POST['params']) == 1)
{
$method = filter_input(INPUT_POST, 'method', FILTER_SANITIZE_STRING);
$class = filter_input(INPUT_POST, 'class', FILTER_SANITIZE_STRING);
$params = filter_input(INPUT_POST, 'params', FILTER_DEFAULT);
$methodToCall = $class . "::" . $method;
echo $appController->callMethod($methodToCall, $params);
}
}
else
{
$method = filter_input(INPUT_POST, 'method', FILTER_SANITIZE_STRING);
$class = filter_input(INPUT_POST, 'class', FILTER_SANITIZE_STRING);
$methodToCall = $class . "::" . $method;
echo $appController->callMethod($methodToCall);
}
}
catch (Exception $e)
{
echo "error";
$file = LOG_PATH . 'router.log';
$date = date("d-m-Y H:i:s", time());
$message = $date . " - " . $e->getMessage() . " \r\n" . $e->getTraceAsString();
file_put_contents($file, $message, FILE_APPEND);
}
Controller.php:
<?php
require_once 'config.php';
require_once 'News.php';
require_once 'User.php';
require_once 'KPI.php';
ini_set("log_errors", 1);
ini_set("error_log", LOG_PATH . "Controller.log");
ini_set('display_errors', 0);
error_reporting(E_ALL);
startIntranetSession();
class Controller
{
public function __construct()
{
$GLOBALS['connection'] = new mysqli(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB, SQL_PORT);
}
public function callMethod($classNameAndMethod, $parameters = null)
{
$callMethodArray = explode("::", $classNameAndMethod);
if (sizeof($callMethodArray) != 2)
{
throw new Exception("Wrong parameter in callMethod()");
}
$className = $callMethodArray[0];
$methodName = $callMethodArray[1];
if ($className == 'User')
{
if (isset($_SESSION['current_user']))
{
$classObject = unserialize($_SESSION['current_user']);
}
else
{
$classObject = new $className();
}
}
else
{
$classObject = new $className();
}
if (!method_exists($classObject, $methodName))
{
throw new Exception("Given method does not exist!");
}
if (!isset($parameters))
{
$parameters = array();
}
if (!$result = call_user_func_array(array($classObject, $methodName), $parameters))
{
throw new Exception("Call_user_func_array failed!");
}
else
{
return $result;
}
}
}