General stuff

Php5 Singleton pattern with magic __get and __set

March 30th, 2008 at 11:41am Under General stuff+ Php+ Php 5

I wanted to reproduce a simple singleton design pattern in PHP 5. After reviewing many overly complex examples, I synthesized to this example.

It also makes use of the PHP5 magic function __get and __set also poorly addressed in web postings. Going for cleaner code I like to see $obj->prop rather than $obj->getProp() and $obj->setProp(value) in the code. But I am greedy and want to have read only and write only props. So I configured the various examples to achieve that goal. As well you can see in the __set and __get methods you may choose to work the props or call a private method that would handle the validation and proper handling of the set and return values. I demonstrated this here.

This is the singleton running with the idea of a single configuration object for an application. It only has one real property named isDebugging for the example.

  1. <?php
  2.  
  3. class Config {
  4.    static private $_instance;
  5.     private $isDebugging = false; // Read write
  6.    private $version = "1.1"   ;  // Read only
  7.    private $cannotReadProp = "x" ;
  8.    public static function getInstance($args = array())
  9.    {
  10.       if(!self::$_instance)
  11.       {
  12.          self::$_instance = new Config();
  13.          
  14.       }
  15.       self::$_instance->setIsDebugging(isset($args['isDebugging']) ? $args['isDebugging'] : self::$_instance->isDebugging);
  16.       return self::$_instance;
  17.    }
  18.  
  19.    private static function setIsDebugging($value)
  20.    {
  21.       self::$_instance->isDebugging = is_bool($value)? $value: self::$_instance->isDebugging;
  22.    
  23.    }
  24.    
  25.    public static function __set($prop, $value)
  26.    {
  27.       if (isset(self::$_instance->$prop))
  28.       {
  29.          switch ($prop)
  30.          {
  31.             case 'isDebugging':
  32.                self::$_instance->setIsDebugging($value);
  33.                break;
  34.  
  35.             default :
  36.                throw new Exception('Cannot write property [' . $prop . ']',1);
  37.          }
  38.  
  39.       }
  40.       else
  41.       {
  42.          throw new Exception('Undefined property [' . $prop . ']',1);
  43.       }
  44.    }
  45.    
  46.    public static function __get($prop)
  47.    {
  48.  
  49.       if (isset(self::$_instance->$prop))
  50.       {
  51.          switch ($prop)
  52.          {
  53.             case 'isDebugging':
  54.                return self::$_instance->isDebugging;
  55.                break;
  56.             
  57.             default :
  58.                throw new Exception('Cannot read property [' . $prop . ']',1);
  59.          }
  60.  
  61.       }
  62.       else
  63.       {
  64.          throw new Exception('Undefined property [' . $prop . ']',1);
  65.       }
  66.    } 
  67.  
  68.  
  69. }
  70. ?>

This is a testing script for the above. Note there are some commented lines for testing the exception thowing.

  1. <?php
  2.    include 'config.inc.php';
  3.    
  4.    // First reference
  5.    $myConfig1 = Config::getInstance();
  6.    
  7.    // Get property
  8.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  9.    // Set property
  10.    echo 'Set $myConfig1->isDebugging = true <br/>';
  11.    $myConfig1->isDebugging = true;
  12.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  13.    
  14.    // Second reference
  15.    echo '<br/>';
  16.    echo 'Add second reference and not getInstance args<br/>';
  17.    echo '$myConfig2 = Config::getInstance(); <br/>';
  18.    $myConfig2 = Config::getInstance();
  19.    
  20.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  21.    echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
  22.    
  23.    // Third reference
  24.    echo '<br/>';
  25.    echo 'Add third reference and change prop via getInstance arg <br/>';
  26.    echo '$myConfig3 = Config::getInstance(array(\'isDebugging\'=>false)); <br/>';
  27.    $myConfig3 = Config::getInstance(array('isDebugging'=>false));
  28.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  29.    echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
  30.    echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
  31.    
  32.    // Set property via second instance
  33.    echo '<br/>';
  34.    echo 'Set property via second instance <br/>';
  35.    echo 'Set $myConfig2->isDebugging = true <br/>';
  36.    $myConfig2->isDebugging = true;
  37.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  38.    echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
  39.    echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
  40.    
  41.    
  42.    
  43.    // Set property to incorrect data type
  44.    echo '<br/>';
  45.    echo 'Set $myConfig1->isDebugging = 123<br/>';
  46.    echo 'No exception for invalid data type and not prop change.<br/>';
  47.    $myConfig1->isDebugging = 123;
  48.    echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
  49.    echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
  50.    echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
  51.  
  52.    // Setter throws undefined property exception
  53.    //$myConfig1->test = true;
  54.    // Getter throws undefined property exception
  55.    //echo '$myConfig1->test:' . $myConfig1->test . '<br/>';
  56.    // Setter throws cannot write property exception
  57.    //$myConfig1->version = '2.2';
  58.    // Setter throws cannot read property exception
  59.    //echo '$myConfig1->cannotReadProp:' . $myConfig1->cannotReadProp . '<br/>';
  60.    
  61. ?>

By Lon Hosford Add comment

Flex LocalConnection Error #2044: Unhandled StatusEvent:. level=error, code=

March 13th, 2008 at 10:50pm Under Flash+ General stuff+ Flex

I have seen this error when trying to use SWFLoader and LocalConnection with a Flash SWF. The problem is related to using the LocalConnection but the Flash SWF has not played the requisite frame where its side of LocalConnection code appears. As such there is no local connection.

To see sample code to overcome this look at my post on using Flex, SWFLoader and LocalConnection: Flex LiveConnection and Legacy Flash SWFs

By Lon Hosford Add comment

Previous Posts


Recent Blog Posts

Categories

Blogroll