Creating a Static Web Form Helper with Restrictive Constructors

Welcome to the final installment of a series that shows you how to use restrictive constructors in PHP 5. With a decent variety of code samples, this series recreates for you a few common scenarios where the implementation of both protected and private constructors can greatly improve the behavior of different classes in the context of a given application.

And now that you’ve been properly introduced to the subject of this series, it’s time to briefly recapitulate the topics that were covered in the last tutorial. In that part of the series I built a basic MySQL abstraction class, which used a private constructor in conjunction with a static method called “getInstance()” to turn the class into a Singleton.

The functionality of this abstraction class was actually quite limited; it only was capable of running queries, fetching rows in data sets, and performing a few more basic tasks. Still, it came in handy for demonstrating how a private constructor can be of great help in implementing the Singleton design pattern in a strict fashion.

However, as I mentioned a moment ago, there are different situations where a restrictive constructor can be employed in a truly useful manner; one of them happens to be when building purely static classes. In most cases (not all of them, naturally), presentation helpers are good candidates for turning into static classes. In the lines to come I’m going to code one for you that will declare a private constructor.

In this particular case, the helper that I’m going to build will take care of rendering different elements of an HTML form in a pretty straightforward way, but it’ll be conceived to be used only out of the object context.

It sounds like a pretty educational experience, right? Thus, to learn the full details regarding the construction of this purely static web form helper, jump ahead and start reading the following lines!

{mospagebreak title=Review: using a private constructor in a Singleton class}

Before I start explaining how to use a private constructor for building a purely static web form helper, it’d be helpful to recall the example developed in the prior part of the series. That example showed how to take advantage of this handy approach when creating a basic Singleton MySQL abstraction class.

Having said that, here’s the definition of this class:

class MySQL

{

    private $_result = NULL;

    private $_link = NULL;

    private $_config = array();

    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;

    }

   

    // private constructor

    private function __construct(array $config)

    {

        if (count($config) < 4)

        {

            throw new Exception(‘Invalid number of connection parameters’);  

        }

        $this->_config = $config;

    }

   

    // prevent cloning class instance

    private function __clone(){}

   

    // connect to MySQL

    private function connect()

    {

        // connect only once

        static $connected = FALSE;

        if ($connected === FALSE)

        {

            list($host, $user, $password, $database) = $this->_config;

            if ((!$this->_link = mysqli_connect($host, $user, $password, $database)))

            {

                throw new Exception(‘Error connecting to MySQL : ‘ . mysqli_connect_error());

            }

            $connected = TRUE;

            unset($host, $user, $password, $database);      

        }

    }

 

 

    // perform query

    public function query($query)

    {

        if (is_string($query) and !empty($query))

        {

            // lazy connect to MySQL

            $this->connect();

            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->_link !== NUlL)

        {

            return mysqli_insert_id($this->_link); 

        }

        return NULL;

       

    }

   

    // 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

Apart from studying the underlying logic of the methods implemented by the above “MySQL” class, you should pay special attention to its constructor, as it’s been declared private. Doing this means the only entry and instantiation point of the class is its static “getInstance()” method, which permits you to turn the class into a Singleton pretty easily.

And now that you understand the rationale behind using a private constructor within the previous MySQL driver, below I listed a short script that shows how to use it for fetching some user-related data from a fictional “users” table. Take a look at it:

// create instance of MySQL class

$db = MySQL::getInstance(array(‘host’, ‘user’, ‘password’, ‘database’));

// fetch users from database table

$db->query(‘SELECT * FROM users’);

// display user data

while ($user = $db->fetch())

{

    echo ‘First Name: ‘ . $user->fname . ‘ Last Name: ‘. $user->lname . ‘ Email: ‘. $user->email . ‘<br />';

}

As the previous script shows, a typical implementation of the Singleton design pattern can be reinforced thanks to the use of a restrictive constructor. On the other hand, the rest of the script is very easy to follow, so I’m not going to waste your time explaining how it works.

Well, having recreated another concrete situation where a private constructor can be really helpful, it’s time to explore other possible cases where this kind of method can be used successfully. Thus, in keeping with the concepts deployed in the introduction, in the course of the following section I’m going to show you how to create a simple — yet functional — HTML form helper class. It will make use of a private constructor to prevent its access within an instance context.

To learn the full details regarding the construction of this static helper, click on the link below and read the next few lines.  

{mospagebreak title=Building a static web form helper class with a private constructor}

As I said in the segment that you just read, there’s another scenario where a private constructor can be truly useful — when building a class that must be used out of the object context, or expressed in other words, as a solely static class.

To demonstrate this concept, in the lines to come I’m going to code a presentational helper, which will be tasked with rendering different controls of an HTML form. Since there won’t be a real need to create instances of it, its originating class will have to be used only statically.

How will this be accomplished? Yes, you guessed right! By declaring its constructor private and its discrete methods static, the helper will be turned into a static class.

Now, take a look at the helper’s definition, which is as follows:

<?php

 

 

class Form

{

  

    // private constructor

    private function __construct(){}

   

   // render <form> opening tag

   public static function open(array $attributes = array())

   { 

       $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 = array())

   { 

       $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 <textarea> tag

   public static function textarea(array $attributes = array())

   { 

       $html = ‘<textarea';

       $content = ”;

       if (!empty($attributes))

       {

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

          {

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

              {

                 if ($attribute === ‘value’)

                 {

                     $content = $value;

                     continue;

                 }

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

              }

          }

       }

       return $html . ‘>’ . $content . ‘</textarea>';

   }

  

   // render </form> closing tag

   public static function close()

   {

       return ‘</form>';

   }

}// End Form class

Aside from implementing a few simple static methods that allow you to render common elements of a web form, such as input boxes, submit buttons and text areas, the previous “Form” class declares its constructor private. In doing so, the class can only be used out of the instance context.

Having demonstrated yet another concrete use of a restrictive constructor in PHP 5 classes, it’s time to give the previous helper a try, so you can see how it functions. Therefore, in the final section of this tutorial I’m going to set up an example for you, which will show the earlier “Form” class in action.

Now, jump forward and read the next segment. It’s only one click away.

{mospagebreak title=Using the previous Form helper class}

If you’re anything like me, then you’ll want to see an example that shows how to use the purely static “Form” helper class. Below I coded a script that employs the helper to build an HTML form that collects data on a fictional user. Here it is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

        <title>Using the static web form helper</title>

    </head>

    <body>

        <h1>Using the static web form helper</h1>

       <?php echo Form::open(array(‘action’ => ‘create’, ‘method’ => ‘post’));?>

       <p>First Name: <?php echo Form::input(array(‘type’ => ‘text’, ‘name’ => ‘fname’));?></p>

       <p>Last Name: <?php echo Form::input(array(‘type’ => ‘text’, ‘name’ => ‘lname’));?></p>

       <p>Email: <?php echo Form::input(array(‘type’ => ‘text’, ‘name’ => ‘email’));?></p>

       <p><?php echo Form::input(array(‘type’ => ‘submit’, ‘name’ => ‘send’, ‘value’ => ‘Create user’));?></p>

       <?php echo Form::close();?>

    </body>

</html>

As the above script shows, it’s extremely easy to build a basic web form by using the static methods provided by the “Form” helper class. Yet, the most important thing to note here is that any attempt to instantiate the class will result in a fatal error being triggered by the PHP engine, thanks to the declaration of its unimplemented private constructor.

And with this final example, I’m finishing this last tutorial of the series. As always, feel free to introduce your own tweaks to all of the sample classes shown, so you can arm yourself with a better background in using restrictive constructors in PHP 5.

Final thoughts

Sad to say, we’ve come to the end of this series. Hopefully, the examples deployed in its tutorials have provided you with the right pointers to help you start using restrictive constructors within your own PHP 5 classes (when applicable, of course).

As you learned in previous examples, even a detail as subtle as changing the level of accessibility of your constructors in certain cases may considerably improve the behavior of their originating classes. This is a concept that you should keep in mind when developing your own web applications.

See you in the next PHP tutorial!

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

chat