Jump to content

PHP SuperGlobal Class Wrapper


berridgeab

Recommended Posts

Hi,

 

I'm looking to create a basic superglobal class wrapper for the PHP super globals. I don't know how to go about setting nested array keys / values within the object.

 

Here is my basic class wrapper -

	class superGlobal 
	{
		protected $superGlobal;
		
		public function __construct(array $superGlobal)
		{
			$this->superGlobal = $superGlobal;
		}
		
		public function set($value, $arrayKey = null)
		{
			if(is_scalar($arrayKey))
			{
				$this->superGlobal[$arrayKey] = $value;
			}
			else
			{
				$this->superGlobal[] = $value;
			}
		}
		
		public function get()
		{
			return $this->superGlobal;
		}
	}

A very simple wrapper. Thanks to the addition of array literials in PHP5.5 I can access single or nested array values easily like below so no problem here.

$nestedArray = array(
    "Unnested Array Value",
    array(
        "Nested Array Value"));

$superGlobal = new \superGlobal($nestedArray);

//Outputs "Unnested Array Value"
echo $superGlobal->get()[0]

//Outputs "Nested Array Value"
echo $superGlobal->get()[1][0]

However I have no idea how to write a "set" function that can accept a nested key . Any ideas? Currently I have to get the nested array, store it in a temporary variable like below.

	//Create superglobal object with random nested array and output
	$superGlobal = new \superGlobal(array());
	$superGlobal->set(array(0 => array(0 => array(0 => "Apples"))), "nestedItem");

	//Output array
	echo "<pre>" , print_r($superGlobal->get(), 1) , "</pre>";
	
	//Grab array and store 
	$temporaryStore = $superGlobal->get()['nestedItem'];
	//Add  new value to the nested array
	$temporaryStore[0][0][1] = "Oranges";
	
	//Now reset the value
	$superGlobal->set($temporaryStore, "nestedItem");
	
	//Output array
	echo "<pre>" , print_r($superGlobal->get(), 1) , "</pre>";

Basically I want to cut out the step of having to store the array into a temporary variable, modify it and reassigning it. I could make the variable public, but I would prefer not to.

 

Link to comment
https://forums.phpfreaks.com/topic/283156-php-superglobal-class-wrapper/
Share on other sites

It looks like you are creating a registry pattern.

 

 


Basically I want to cut out the step of having to store the array into a temporary variable, modify it and reassigning it

 

That would mean making the class aware of what you are storing in it, which I feel goes beyong the scope of what a superglobal of registry is supposed to do.

I'd feel more comfortable with a "fruitlist" object that you can store in the registry, then you can modify that by getting it from the registry and calling a modifier method on it to replace the element.

untested

 

 

class RecursiveArrayWrapper extends \ArrayObject {
  public function offsetGet($offset) {
    $data = parent::offsetGet($offset);
    if (is_array($data)) {
      return new static($data, $this->getFlags(), $this->getIteratorClass());
    }
    return $data;
  }
  
  // add functionality as needed
  public function merge($array) {
    if ($array instanceof self) {
      $array = $array->getArrayCopy();
    }
    $this->exchangeArray(array_merge($this->getArrayCopy(), $array));
    return $this;
  }
}

$array = new RecursiveArrayWrapper(array(
  'foo' => array('bar' => array('bat' => 'baz'))
), ArrayObject::ARRAY_AS_PROPS);

var_dump($array->foo->bar->bat);
var_dump($array->foo->merge(array('bar' => array('bat' => 'foo')))->bar->bat);
Does exactly what you want but instead of calling it something as meaningless as superGlobal, I called it something so that it can be re-used for something more then just as a superGlobal container (which it really wasn't either). This is kinda more what I would call it:

 

class HttpRequest {
  public $get;
  public $post;
  public $cookie;
  public $session;
  public $server;
  public $files;
  public $env;
  public $globals;
  
  public function __construct() {
    foreach (array('get', 'post', 'cookie', 'session', 'server', 'files', 'env', 'globals') as $superGlobal) {
      if (isset(${'_' . strtoupper($superGlobal)})) {
        $this->$superGlobal = new RecursiveArrayWrapper(${'_' . strtoupper($superGlobal)}, ArrayObject::ARRAY_AS_PROPS);
      }
    }
  }
}

$request = new HttpRequest;
var_dump($request->get->foo);

Very nice ignace, the HTTPRequest class doesn't get filled but I think thats down to not being able to use variable variables with PHPs superglobals.

 

http://php.net/manual/en/language.variables.variable.php

 

Anyway thats a minor issue, you've gave me some ideas and a direction to follow. Thanks for your response.

 

Edit - Updated HTTPRequest class to get around variable variable issue.

class HttpRequest
{
    public $get;
    public $post;
    public $cookie;
    public $session;
    public $server;
    public $files;
    public $env;

    public function __construct()
    {
        foreach (array('get', 'post', 'cookie', 'session', 'server', 'files', 'env') as $superGlobal)
        {
            $globals = $GLOBALS;
            if(isset($globals['_' . strtoupper($superGlobal)]))
            {
                $this->$superGlobal = new RecursiveArrayWrapper($globals['_' . strtoupper($superGlobal)], ArrayObject::ARRAY_AS_PROPS);
            }            
        }
    }
}

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.