Page 1 of 1

Making MySQLi connection avaliable to all MVC modules...

Posted: Sat May 17, 2008 3:46 pm
by kilbad
I have MVC classes I coded myself (see below) which I instantiate in my index.php5 file. Also, at the beginning of my index file, I open a MySQLi connection, and then close it at the end of the index file. My question is this, how can I make that MySQLi object/connection available to all the MVC modules. Restated, I don't want to have to constantly open up new connections for each module.

Any other feedback is appreciated as well. Thanks again!

My index.php5 file

Code: Select all

 
<?php
 
//Setting full error reporting
error_reporting(E_ALL);
 
//Initializing session
session_start();
 
//General includes
require_once 'configurations.php5';               //General configurations
require_once MVC_ROOT . '/MysqliSetConnect.php5'; //MySQLi Settings & Connection
require_once MVC_ROOT . '/Authentication.php5';   //User authentication
 
//Including MVC classes and instatiating front controller
require_once MVC_ROOT . '/ModelViewController.php5';
$controller = FrontController::getInstance();
$controller->setPageDir(MVC_ROOT);
$controller->dispatch(false);
 
//Closing MySQLi object created in MysqliSetConnect.php5 (included above)
$mysqli->close();
 
?>
 
My MysqliSetConnect.php5 file

Code: Select all

 
<?php
 
//Setting constant database connection settings
define("MYSQL_SERVER", 'mysql.internal');
define("MYSQL_SERVER_USERNAME", 'example_user');
define("MYSQL_SERVER_PASSWORD", 'example_password');
 
/* Establishing general MySQLi connection for all modules with NO database
 * selected
 */
$mysqli = new mysqli(MYSQL_SERVER, MYSQL_SERVER_USERNAME, MYSQL_SERVER_PASSWORD);
 
?>
 
My ModelViewController.php5 file

Code: Select all

 
<?php
 
class FrontController extends ActionController {
 
    //Declaring variable(s)
    private static $instance;
    protected $controller;
 
    public function __construct(){}
 
    //Starting new instance of this class with a singleton pattern
    public static function getInstance() {
        if(!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
 
    public function dispatch($throwExceptions = false) {
 
        /*  
            Checking for the GET variables $module and $action, and, if present,
            will strip them down with a regular expression function with a white
            list of allowed characters, removing anything that is not a letter,
            number, underscore or hyphen.
        */
        $regex  = '/[^-_A-z0-9]++/';
        $module = isset($_GET['module']) ? preg_replace($regex, '', $_GET['module']) : 'home';
        $action = isset($_GET['action']) ? preg_replace($regex, '', $_GET['action']) : 'frontpage';
 
        /*
            Generating Actions class filename (example: HomeActions) and path to
            that class (example: home/HomeActions.php5), checking if $file is a
            valid file, and then, if so, requiring that file.
        */
        $class = ucfirst($module) . 'Actions';
        $file  = $this->pageDir . '/' . $module . '/' . $class . '.php5';
 
        if (!is_file($file)) {
            throw new FrontControllerException('Page not found!');
        }
 
        require_once $file;
 
        /*  
            Creating a new instance of the Actions class (example: $controller
            = new HomeActions();), and passing page directory variable to the
            ActionController class.
        */
        $controller = new $class();
        $controller->setPageDir($this->pageDir);
 
        try {
            //Using the setModule method in the ActionController class
            $controller->setModule($module);
 
            /*
                The ActionController dispatchAction method Checks if the method
                exists, then runs the displayView function in the
                ActionController class.
            */    
            $controller->dispatchAction($action);
        }
        catch(Exception $error) {
 
            /*
                An exception has occurred, and will be displayed if
                $throwExceptions is set to true.
            */
            if($throwExceptions) {
                echo $error->errorMessage($error); //Full exception echoed
            } else {
                echo $error->errorMessage(null); //Simple error messaged echoed
            }
        }
    }
}
 
abstract class ActionController {
 
    //Declaring variable(s)
    protected $pageDir;
    protected $module;
    protected $viewData = array();
    
    public function __construct(){
        
        /*
            Setting variables for objects external to the MVC that are used in
            multiple modules.  These objects add NO functionality to the actual
            MVC classes, but are used by multiple modules.
         */
        $this->auth = MysqliAuthentication::getInstance(); //User authentication
    }
    
    public function setPageDir($pageDir){
        $this->pageDir = $pageDir;
    }
 
    public function setModule($module) {
        $this->module = $module;
    }
 
    public function getModule() {
        return $this->module;
    }
 
    //Placing a value in the $viewData array at the key position
    public function setVar($key, $value) {
        $this->viewData[$key] = $value;
    }
 
    //Returns a value from the $viewData array located at the key position
    public function getVar($key) {
        if (array_key_exists($key, $this->viewData)) {
            return $this->viewData[$key];
        }
    }
 
    public function getViewData($viewData) {
        $this->viewData = $viewData;
    }
 
    /*
        Checking for actionMethod in the Actions class (example: doFrontpage()
        within home/HomeActions.php5) with the method_exists function and, if
        present, the actionMethod and displayView functions are executed.
    */  
    public function dispatchAction($action) {
        $actionMethod = 'do' . ucfirst($action);
        if (!method_exists($this, $actionMethod)) {
            throw new FrontControllerException('Page not found!');
        }
        $this->$actionMethod();
        $this->displayView($action);
    }
 
    public function displayView($action) {
        if (!is_file($this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php5')) {
            throw new FrontControllerException('Page not found!');
        }
 
        //Setting $this->actionView to the path of the action View file
        $this->actionView = $this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php5';
 
        /*
            Creating a new instance of the View class and passing the $pageDir,
            $viewData, and actionView variables
        */  
        $view = new View();
        $view->setPageDir($this->pageDir);
        $view->getViewData($this->viewData);
        $view->setVar('actionView',$this->actionView);
        $view->render();
    }
}
 
class View extends ActionController {
 
    public function render() {
 
        //Including default template settings
        require_once $this->pageDir . '/defaultTplSettings.php5';
 
        /*
            Merging the default template variables with variables provided in
            the $this->viewData array, taken from the Actions class, giving
            priority to those provided by the action class, then extracting the
            array with the extract() function, which creates a variable for
            every array value, and the name of the value (the variable name) is
            the key's value.
        */
        $templateSettings = array_merge($defaultTemplateSettings, $this->viewData);
        extract($templateSettings, EXTR_OVERWRITE);
 
        //Including template file within which the action View file is included
        require_once $this->pageDir . '/default.tpl';
    }
}
 
class FrontControllerException extends Exception {
    public function errorMessage($error) {
        
        /*
            If and throwExceptions is true, then the full exception will be
            returned.
        */
        $errorMessage = isset($error) ? $error : $this->getMessage();
        return $errorMessage;
    }
}
 
?>
 

Re: Making MySQLi connection avaliable to all MVC modules...

Posted: Sat May 17, 2008 4:00 pm
by Christopher
Pass in a Registry or maybe use DI...

Re: Making MySQLi connection avaliable to all MVC modules...

Posted: Sat May 17, 2008 4:05 pm
by kilbad
Thank you for your replies on both my posts!

Two follow-up questions: (1) what does DI stand for, and (2) regardless of whether I use a registry class or DI(?), could you give me some basic example code of how you provide the MySQLi object to module classes?

Overall, I just want to keep it simple and keep my logic separated well.

Thanks again.

Re: Making MySQLi connection avaliable to all MVC modules...

Posted: Sat May 17, 2008 4:20 pm
by Christopher
DI is Dependency injection. Essentially the line "$controller->setModule($module);" is doing just that in your Front Controller. Look up the Registry pattern and you will see how it works.