Multi-dimensional and associative POST arrays

Filed in PHP Leave a comment

Anyone doing web development requiring client-server interaction is familiar with GET and POST. (There are others as well, including PUT, DELETE, and so on. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html for the list.) And pretty quickly most folks become aware of the ability to pass arrays as request parameters. For example:


<form method="post" action="http://www.example.com/myformproc.php">
  <fieldset>
    <legend>Notification Methods<legend>
    <input type="checkbox" name="note_opts[]" value="email" id="note_opt_email"><label for="note_opt_email">E-Mail</label>
    <input type="checkbox" name="note_opts[]" value="text" id="note_opt_text"><label for="note_opt_text">Text Message</label>
    ... etc ...
  </fieldset>
</form>

On the server side, if the user selected any of the notification options, you would have an array in a POST variable, ‘note_opts’. In PHP, for example you would see an array $_POST['note_opts']. That array would contain the values of the selected options. The indexes of those values would be numerically indexed in the usual, default, manner.

What if we’re editing the options for multiple objects. Each of our objects has an id number and 0 or more of the options.

What I often see is:


    <input type="checkbox" name="obj_<?php echo $object->getID(); ?>_note_opts[]" value="email" id="note_opt_email">

And then we end up having to parse the id out of the variable name…

Far better to do something like:


    <input type="checkbox" name="note_opts[<?php echo $object->getID(); ?>][]" value="email" id="note_opt_email">

In this way we get a 2 dimensional array of note_opts. The object with id ’1′ is simply $_POST['note_opts'][1].

This also makes it easy to loop through the objects getting their ids along the way


$note_opts = $_POST['note_opts'];
if (is_array($note_opts)) {
  foreach($note_opts as $obj_id=>$opt_set) {
    $obj = MyType::get($obj_id);
    if (!$obj) {
      addError("Failed to get object (".$obj_id.")";);
    } elseif (!$obj->setOptions($opt_set)) {
      addError("Failed to set options for ".$obj->getName()." (".$obj_id.")";);
    }
  }
}

It’s not a big leap from note_opts[] to note_opts[2][email_options][address]. Organizationally it makes life a lot easier, especially if there is any complexity to your data. This way hierarchical data can easily be represented in nested arrays. One final comment, please note that the named array indices like email_options and address are not enclosed in quotes.

Singletons in JavaScript

Filed in JavaScript | PHP 2 Comments

I use singletons all over the PirateQuesting code, but I’ve never explained the idea here, nor how they are different from singletons in other languages.

Anyone familiar with common design patterns knows how singletons work in the vast majority of languages. For a PHP example, see this post.

In JavaScript there are basically two main ways to create a singleton. One is use immediate instantiation so that the class may not be instantiated again. The second is closer to the traditional singleton pattern, however, since there are no private members or constructors, we can get around this by using a nested ‘class’ constructor — and there are two ways to accomplish this.

The first way is done as follows:

var singleton = new (function Singleton() {
                               this.value = 12;
                             } )();

alert(singleton.value); // alerts 12;

var singly = new Singleton(); // Singleton is not defined.

alert(singleton instanceof Singleton); // Singleton is not defined

In the above, the constructor name, Singleton, isn’t really necessary. While it can’t be used to instantiate the Singleton again, it also can’t be used with instanceof or typeof so feel free to leave it out if you want; leaving it in, does make it more obvious what is happening though.

And the second way (version 1):

var Singleton = (function () {
  var instance = null;

  function Singleton() {
    this.value = 12;
  }

  this.getInstance = function () {
    if (instance === null) {
      instance = new Singleton();
    }
    return instance;
  }
})();

var singleton = Singleton.getInstance();
alert(singleton.value); // alerts 12;

var singly = new Singleton(); // Singleton is not a construct

alert(singleton instanceof Singleton); //invalid 'instanceof' operand Singleton

The above is just an anonymous function being called immediately (note the () after the function declaration). Inside the function it declares a pseudo-private member called instance, a pseudo-private constructor, Singleton, and a getInstance method. The getInstance method can see instance due to closure, while the outside world has no idea that it exists.

And finally, the second way (version 2):

var Singleton = {

  getInstance : (function() {

    var instance;
    function Singleton() {
      this.value = 12;
    }

    return function () {
      if (instance == null) {
	    instance = new Singleton();
      }
      return instance;

    }

  })()
}

var singleton = Singleton.getInstance();
alert(singleton.value);

var singly = new Singleton(); // Singleton is not a constructor

alert(singleton instanceof Singleton); //invalid 'instanceof' operand Singleton

In this final example, all of the logic is put into the getInstance function which is the result of a self-calling function which itself returns a function. Yeah, it’s a little hard to follow, but basically the returned function has visibility of instance and the Singleton constructor due to closure.

As a closing note, it’s worth pointing out that although all of the above methods do not permit a second instance construction, they also do not allow use of typeof or instanceof for type verification.

Update

Based on a comment below by Peter Robinett, I’ve come up with a different way to do this, which allows for instanceof and typeof and seems to be an all-round good solution to the problem. It does not, however use the classical getInstance method, but works well all the same.

var Singleton = function () {
  var instantiated = false;

  return function () {
    if (instantiated) {
      throw "Singleton already instantiated";
    }
    instantiated = true;
    this.value=12;
    }
}()

var singleton = new Singleton();
alert(singleton.value);    //alerts 12
alert(singleton instanceof Singleton);  alerts true 

var singly = new Singelton(); //throws exception and cannot be instantiated

, ,

Singletons in PHP

Filed in PHP 1 Comment

I write PHP regularly in my job, but this is the first post on Ashita.org on a PHP subject. One interesting problem recently was how to make Singletons in PHP from a generic base class and extended where necessary. First, an introduction: Singletons are an incredibly common and useful design pattern. Singletons are used to ensure there is only one instance of a class and the class cannot be instantiated directly from outside the class.

  • Simple Case

    In PHP, the singleton pattern is as easy as making a class with a private or protected constructor and a static method to get the single instance.

    
    class Singleton
    {
      private $instance;
    
      private function __construct()
      {
      }
    
      private function __clone()
      {
        //do nothing
      }
    
      public static function getInstance()
      {
        if (is_null(self::$instance))
        {
          self::$instance = new self();
        }
        return self::$instance;
      }
    }
    
    • Note

      One thing to note about the code above is the __clone() method. Unless overridden, the default __clone() method creates a new object with all of the properties copied over. Obviously, this goes against the principles of a singleton — there should be only one instance.

    This technique allows the class author to ensure only one instance is available and that any changes made to it are shared by all references to this object, but what if we wanted to use this pattern more than once. Wouldn’t it be better to extend this class? Doing so would require some changes… (and in this implementation, it requires php 5.3 or higher)

  • Extendable Singleton

    
    abstract class Singleton
    {
      public static function getInstance()
      {
        $class = get_called_class();
        if (is_null($class::$instance))
        {
          $class::$instance = new $class();
        }
        return $class::$instance;
      }
    
    }
    
    class Database extends Singleton
    {
    
      protected static $instance;
    
      protected function __construct()
      {
        //do DB init work here
      }
    
      private function __clone()
      { }
    
      //include functions to act on DB here
    
    }
    

    basically, the only thing classes extending Singleton would need to do is mark their __construct method protected, their __clone method can remain private, and to include a protected static $instance class variable. Further simplifications could be made, but it seems a good base to work from. (Note that the above example requires a somewhat quirky behaviour in php that allows subclasses to inherit static methods.)

, ,

TOP