As usual, before I start building the HTML form helper mentioned in the introduction, I'm going to show all of the source files created so far. They are the building blocks of this sample PHP framework. Having said that, here’s the list of the files, starting with the “.htaccess” file: (.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 As seem above, aside from handling custom and default exceptions, as well as autoloading classes, the front controller bootstraps a dispatcher class. Below you will see the short definition of this class: (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 Having shown the signature of the router/dispatcher class, and taking into account that the underlying persistent storage mechanism used by the framework will be a MySQL database, it was necessary to build a class that abstracted accesses to that particular RDBMS. The class responsible for doing that is called, not surprisingly, “MySQL,” and it looks like this: (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 Finally, I decided to add to the framework the ability to sanitize user-supplied data at a basic level through a simple input handling class, whose definition is shown below: (Input.php) <?php class Input { private static $instance = NULL;
// get Singleton instance of Input class public static function getInstance() { if (self::$instance === NULL) { self::$instance = new self; } return self::$instance; }
// get $_GET variable public static function get($var = NULL) { if (!isset($_GET[$var])) { return $var; } return mysql_escape_string(trim($_GET[$var])); }
// get $_POST variable public static function post($var = NULL) { if (!isset($_POST[$var])) { return $var; } return mysql_escape_string(trim($_POST[$var])); } }// End Input class That’s all of the source files that comprise the MVC framework up to now. Of course, it’s clear to see that it still lacks some important features that should be added sooner or later. For example, it needs to be able to cache database queries and automatically generate code, to make it easier to construct HTML forms and dynamic URLs. Bearing in mind some of these relevant requisites, in the following section I’m going to add to the framework another core class. It will be charged with rendering different elements of a web form, such as text and password boxes, as well as radio and submit buttons. As you know, this kind of class is also known as a form helper, and as I mentioned a moment ago, its partial definition will be shown in the segment to come. Thus, to get there, simply click on the link below and keep reading.
blog comments powered by Disqus |
|
|
|
|
|
|
|