...

Pseudo Global Variables using an Overloaded Singleton class

Northie
08-18-2008, 03:12 PM
I'm in the middle of building myself a PHP 5 framework and i am utilising such features as __autolaod() and the singleton design pattern.

I use singletons to persist data around a request that may invoke over 20 different objects......then i read about 'overloading' - a way to dynamically create class members and methods - and came up with this:


class myVars {
/**
* @var object instance of self, see public static function myVars()
*/
private static $instance;

/**
* @var settings held here
*/
public $data = array();

/**
* private construct, does nothing
*/

private function __contrsuct() {

}

/**
* @return object an instance of it's self
*/

public static function Load() {
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}

/**
* __set
* magic method called when overloading the object
*
* @param str $key name of variable, used as array key
* @param mixed $value Value of variable
* @return bool an instance of it's self
*/
public function __set($key,$value) {
$this->data[$key] = $value;
return true;
}

/**
* __get
* magic method called when retrieving overloaded object member
*
* @param str $key name of variable, used as array key
* @return mixed value of key or null
*/
public function __get($key) {
if(array_key_exists($key,$this->data)) {
return $this->data[$key];
} else {
return null;
}
}

/**
* Prevent cloning
*/

public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}

}

Example 1
Explicit call to class name
Gloabal in all contexts where the class is defined

myVars::Load()->a = 'Hello World';
echo myVars::Load()->a; //echos Hello World

Example 2
Instance of object created
Retains the scope of $o

$o = myVars::Load();
$o->b = 'Hello Again';
echo $o->b; //echos Hello Again

Example 3
use inside another object
retains scope of instance, but two different class members (even with different visibility) can access the 'global' variables

class someExample {

public $myGlobals = "";
private $myPrivGlobals = "";

public function __construct() {
$this->myGlobals = myVars::Load();
$this->myPrivGlobals = myVars::Load();

$this->egFn();
}

private function egFn() {
$this->myPrivGlobals->c = 'Still here?'."<br />\n";
}

public function egFn2() {
echo $this->myGlobals->a; //Hello World
echo $this->myGlobals->b; //Hello Again
echo $this->myGlobals->c; //Still here?
echo $this->myPrivGlobals->c; //Still here?
}
}

$x = new someExample;
$x->egFn2();


I thought this was quite interesting (call me a geek!) and would be interested in other people's thoughts

possible further reading:
http://www.php.net/manual/en/language.oop5.patterns.php
http://www.php.net/manual/en/language.oop5.overloading.php
http://www.php.net/manual/en/language.oop5.autoload.php

I parse an ini file of settings and class names/locations into a singleton, and then access tis singleton in the __autoload function

Fou-Lu
08-18-2008, 10:09 PM
Overloading does not actually mean to create dynamic data. PHP doesn't support real overloading, but treats a few methods as fallbacks instead: __get, __set, and __call. These are designed so that if you access a variable or method without a proper scope, it filters through these fallback methods essentially allowing you to capture the fallback and act accordingly.
This code is a simulation for property creations. This is not a good idea. If you need to store unknown or undefinable data inside of an object, you are better off using an actual property to store these in, and providing it with the proper accessor/mutators. This will prevent confusion between data stored by the object and the actual properties of the object.
Nice use of objects otherwise.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum