In case you haven't read the previous part of the series, where I added to the framework a basic MySQL handling class, below I reintroduced all of the source files created up to now. This way you can more quickly grasp how they interact with each other. So, first here's the ".htaccess" file that redirects all of the user requests to "index.php": (.htaccess file) # Turn on URL rewriting engine RewriteEngine On # Disable rewriting for existing files or directories RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # redirect all other requests to index.php RewriteRule ^.*$ index.php [PT,L] Now, it's time to show the framework's front controller, which looks like this: (index.php) <?php // framework's front controller // specify parameters for autoloading classes spl_autoload_register(NULL, FALSE); spl_autoload_extensions('.php'); spl_autoload_register(array('Autoloader', 'load')); // define custom ClassNotFoundException exception class class ClassNotFoundException extends Exception{} // define Autoloader class class Autoloader { // attempt to autoload a specified class public static function load($class) { if (class_exists($class, FALSE)) { return; } $file = $class . '.php'; if (!file_exists($file)) { eval('class ' . $class . '{}'); throw new Exception('File ' . $file . ' not found.'); } require_once($file); unset($file); if (!class_exists($class, FALSE)) { eval('class ' . $class . '{}'); throw new ClassNotFoundException('Class ' . $class . ' not found.'); } } } // handle request and dispatch it to the appropriate controller try{ Dispatcher::dispatch(); } catch (ClassNotFoundException $e){ echo $e->getMessage(); exit(); } catch (Exception $e){ echo $e->getMessage(); exit(); }// End front controller Not too hard to follow, right? Also, as you may have noticed, the above "index.php" file bootstraps a router/dispatches class. Its definition is below: (Dispatcher.php) <?php class Dispatcher { // dispatch request to the appropriate controller/method public static function dispatch() { $url = explode('/', trim($_SERVER['REQUEST_URI'], '/')); array_shift($url); // get controller name $controller = !empty($url[0]) ? $url[0] . 'Controller' : 'DefaultController'; // get method name of controller $method = !empty($url[1]) ? $url[1] : 'index'; // get argument passed in to the method $arg = !empty($url[2]) ? $url[2] : NULL; // create controller instance and call the specified method $cont = new $controller; $cont->$method($arg); } }// End Dispatcher class And after this quick round-up, here's the class that abstracts the access to MySQL. Take a look, please: (MySQL.php) <?php class MySQL { private $result = NULL; private $link = NULL; private static $instance = NULL; // return Singleton instance of MySQL class public static function getInstance(array $config = array()) { if (self::$instance === NULL) { self::$instance = new self($config); } return self::$instance; }
// constructor public function __construct(array $config = array()) { // grab connection parameters list($host, $user, $password, $database) = $config; if ((!$this->link = mysqli_connect($host, $user, $password, $database))) { throw new Exception('Error connecting to MySQL : ' . mysqli_connect_error()); } } // perform query public function query($query) { if (is_string($query) and !empty($query)) { if ((!$this->result = mysqli_query($this->link, $query))) { throw new Exception('Error performing query ' . $query . ' Message : ' . mysqli_error($this->link)); } } }
// fetch row from result set public function fetch() { if ((!$row = mysqli_fetch_object($this->result))) { mysqli_free_result($this->result); return FALSE; } return $row; } // get insertion ID public function getInsertID() { if ($this->result !== NULL) { return mysqli_insert_id($this->link); } return FALSE; }
// count rows in result set public function countRows() { if ($this->result !== NULL) { return mysqli_num_rows($this->result); } return 0; }
// close the database connection function __destruct() { is_resource($this->link) and mysqli_close($this->link); } }// End MySQL class So far, so good. Since all of the source files shown above are pretty easy to grasp, I'm not going to spend more time explaining how they work. Nonetheless, it's fair to mention here that the framework in its current stage lacks an important feature. What is it? Well, it'd be desirable to give to it the ability to perform some kind of sanitizing process on user-supplied data, which can be useful for preventing SQL injections. With that idea in mind, in the next section I'm going to incorporate into the framework an input handling class, which will accomplish the aforementioned sanitizing task in a simple manner. To learn the full details regarding the development of this class, jump ahead and read the following segment. It's only one click away.
blog comments powered by Disqus |
|
|
|
|
|
|
|