Adding a Form Helper to an MVC-based Framework in PHP 5

In this fifth episode of the series, I start building an HTML form helper class to add to this sample MVC framework the ability to render some basic form elements.

Since the web is in constant evolution, developing applications for it often requires mastering different disciplines that range from using client-side technologies such as (X)HTML, CSS and JavaScript, to working with server-side languages like PHP, Ruby and SQL, among others.

While all of these technologies are quite different from each other, they do share one common thing. Whether you are building a simple JavaScript program or a full-fledged PHP application, it frequently involves performing a lot of repetitive tasks, which is an annoying and time-consuming process.

To prevent web developers from doing the same things over and over again, many client and server-side frameworks have emerged in the last few years. Some of them have become so successful, that for many people it is nearly impossible to work without them.

In the case of PHP, frameworks such as Zend, Kohana and CakePHP, to name just a few, allow programmers to quickly build web applications based on the Model-View-Controller design pattern. Still, they’re only a part of a long list that includes other valuable software stacks. Having so many frameworks available to choose from nowadays, is it really worthwhile to learn how to build one on your own?

While at first sight this seems to be a pointless task, going through the entire development process can be really educational, whether you want to learn how to apply the MVC pattern in PHP, or gain a basic understanding of the inner workings of well-established frameworks.

So, if you’re interested in grasping the basic concepts that surround the creation of an MVC-based framework in PHP 5, then you should start reading this series of articles. In it, you’ll learn in a step-by-step fashion how to create a stack of extensible classes that can be put to work together under the schema followed by the Model-View-Controller design pattern.

Speaking of classes, you’ll surely recall that I left off the last tutorial adding to the framework being constructed a class that sanitizes user-supplied input in a pretty basic way. However, it’s necessary to add to it many other features, including the ability to render HTML forms. So, in the following lines I’m going to build a form helper class, which will perform the aforementioned rendering task in a painless manner.

Now, to learn how this form helper class will be developed, jump ahead and start reading!

{mospagebreak title=Review: the framework’s source files}

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.

{mospagebreak title=Building a basic web form helper class}

Expressed in simple terms, the web form helper class that I plan to build in the following lines will be pretty basic. It will implement some simple methods aimed at rendering different form elements, including different types of input boxes, radio buttons, text areas and so forth. So far, nothing unexpected, right?

In most cases, the methods of this helper will be called statically to prevent an  unnecessary instantiation of the originating class. However, similarly to other classes developed before, this one will implement a “getInstance()” method that will return a Singleton instance of the class in question.

Now that I have outlined how the form helper is going to work, please take a look at its partial source code, which looks as simple as this:

class Form

{

                private static $instance = NULL;

               

                // get Singleton instance of Form class

                public static function getInstance()

                {

                                if (self::$instance === NULL)

                                {

                                                self::$instance = new self;

                                }

                                return self::$instance;

                }

               

                // render <form> opening tag

                public static function open(array $attributes)

                {             

                                $html = ‘<form’;

                                if (!empty($attributes))

                                {

                                                foreach ($attributes as $attribute => $value)

                                                {

                                                                if (in_array($attribute, array(‘action’, ‘method’, ‘id’, ‘class’, ‘enctype’)) and !empty($value))

                                                                {

                                                                                // assign default value to ‘method’ attribute

                                                                                if ($attribute === ‘method’ and ($value !== ‘post’ or $value !== ‘get’))

                                                                                {

                                                                                                $value = ‘post’;

                                                                                }

                                                                                $html .= ‘ ‘ . $attribute . ‘="’ . $value . ‘"’;

                                                                }

                                                }

                                }

                                return $html . ‘>’;

                }

               

                // render </form> closing tag

                public static function close()

                {

                                return ‘</form>’;

                }

}// End Form class

Apart from the implementation of the aforementioned “getInstance()” method that returns a Singleton object, which may look a bit tricky, the rest of the logic of the above “Form” class should be extremely easy to follow for you. As shown above, the class defines just a couple of methods for rendering the opening and closing tags of an HTML form. Period.

These methods have been declared static, meaning that there’s no need to create an instance of the helper to invoke them directly. Also, it must be admitted that the class in its current incarnation could be largely improved, to make it more functional. But in keeping with the requirements of this particular project, it’ll be kept simple.

So far, so good, right? At this moment, I’m sure that you’ve grasped how the previous “Form” class does its thing, so it’s time to add more methods to it. In the last segment of this tutorial I’m going to code one that will be tasked with rendering some common form input elements.

To learn how this new method will be implemented, go ahead and read the following section. It’s only one click away.

{mospagebreak title=Adding a method to render input elements}

In reality, coding within the previous web form helper class a method that constructs input elements is a pretty straightforward process that you’ll grasp in a snap, trust me. To demonstrate that my claim is true, below I listed the improved version of the helper, this time including the method in question. Take a close look at the following code fragment, please:

(Form.php)

class Form

{

                private static $instance = NULL;

               

                // get Singleton instance of Form class

                public static function getInstance()

                {

                                if (self::$instance === NULL)

                                {

                                                self::$instance = new self;

                                }

                                return self::$instance;

                }

               

                // render <form> opening tag

                public static function open(array $attributes)

                {             

                                $html = ‘<form’;

                                if (!empty($attributes))

                                {

                                                foreach ($attributes as $attribute => $value)

                                                {

                                                                if (in_array($attribute, array(‘action’, ‘method’, ‘id’, ‘class’, ‘enctype’)) and !empty($value))

                                                                {

                                                                                // assign default value to ‘method’ attribute

                                                                                if ($attribute === ‘method’ and ($value !== ‘post’ or $value !== ‘get’))

                                                                                {

                                                                                                $value = ‘post’;

                                                                                }

                                                                                $html .= ‘ ‘ . $attribute . ‘="’ . $value . ‘"’;

                                                                }

                                                }

                                }

                                return $html . ‘>’;

                }

               

                // render <input> tag

                public static function input(array $attributes)

                {             

                                $html = ‘<input’;

                                if (!empty($attributes))

                                {

                                                foreach ($attributes as $attribute => $value)

                                                {

                                                                if (in_array($attribute, array(‘type’, ‘id’, ‘class’, ‘name’, ‘value’)) and !empty($value))

                                                                {

                                                                                $html .= ‘ ‘ . $attribute . ‘="’ . $value . ‘"’;

                                                                }

                                                }

                                }

                                return $html . ‘>’;

                }

               

                // render </form> closing tag

                public static function close()

                {

                                return ‘</form>’;

                }

}// End Form class

There you have it. Now the helper has a new static method called “input(),” which can be used for creating text boxes and password fields, radio and submit buttons, and other common controls.

To be frank, after adding to the “Form” class the method that renders input elements, it’s starting to look a bit more functional. Naturally, there’s plenty of room to extend the class’ capabilities, but for the moment I’m going to keep its driving logic this basic, you can spot more clearly how it fits into the schema of this example framework.

Feel free to tweak the source code of all the classes developed so far. 

Final thoughts

Over this fifth episode of the series, I started building an HTML form helper class with the purpose of adding to this sample MVC framework the ability to render some basic form elements. At this point, this helper class is capable only of constructing input controls, including text and password boxes, radio and file buttons, and so forth.

This isn’t enough functional for the purposes of this series. In the next tutorial I’m going to put the final touches on this helper class by enabling it to create HTML text areas.

Want to see how this will be accomplished? Then don’t miss the upcoming tutorial!

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye