Javascript style object literals in PHP

1 Flares Filament.io 1 Flares ×

Javascript object literals look like this

var a = {
    'var_1' : 'Hello' ,
    'var_2' : 'World' ,

    'get' : function()
    {
        alert(a.var_1);
    }
};

As similar thing can be done in PHP using anonymous functions (since 5.3)

Quick example


$a = [
	'var_1' => 'Hello World' ,
	
	'happy' => function() use(&$a)
	{
		echo $a['var_1'];
	}
];

$a['happy']();   //outputs Hello World

Looks interesting ? Ofcourse! Since version 5.3 Php added support for closures and that feature has been used above to create javascript style object literals.

The use(&$a) expression makes the variable $a available inside the function happy.

Adding more properties

$a = [
	'var_1' => 'Hello World' ,
	
	'happy' => function() use(&$a)
	{
		echo $a['var_1'];
	}
];

$a['happy']();

//add more properties, both variables and functions
$a['song'] = 'Ring a Roses';

$a['sing'] = function() use(&$a)
{
	echo $a['song'];
};

$a['sing']();

More properties can be added initial declaration.

The object literals shown above are singletons. They cannot be copied and since their is no class, its not possible to create another object of same structure, without writing it again of course.

Wrapping in a function can help

function get_object()
{
	$a = [
		'var_1' => 'Hello World' ,
		
		'happy' => function() use(&$a)
		{
			echo $a['var_1'];
		}
	];
	
	return $a;
}

$k = get_object();
$k2 = get_object();

$k['happy']();

$k2['happy'] = function() use(&$k)
{
	echo "Happier";
};

$k2['happy']();

The function get_object acts like a constructor creating objects (literals).

Object style syntax

The syntax used so far is like that of associative arrays. The neater object style syntax can also be used.

$a = (object) [
	'var_1' => 'Hello World' ,
	
	'happy' => function() use(&$a)
	{
		echo $a->var_1;
	}
];

//this will not work
//$a->happy();

//but this will work
$b = $a->happy;
$b();

The above has a small drawback. That $a->happy() makes php complain that happy is not a function of object $a. So the same property has to be assigned to another variable and then that variable is used to call the function.

There is an alternative to make it work. Using the __call magic method. But that would ofcourse need a proper class. Lets take an example

class js_object
{
	function __call($name, $args) 
	{
		if (is_callable($this->$name)) 
		{
			//call the function
			return call_user_func_array($this->$name, $args);
		}
	}
}

$a = new js_object;

//add properties
$a->song = 'Ring a Roses';

$a->sing = function() use(&$a)
{
	echo $a->song;
};

$a->sing();  //Output Ring a Roses






These can be cloned as well


class js_object
{
	function __call($name, $args) 
	{
		if (is_callable($this->$name)) 
		{
			//call the function
			return call_user_func_array($this->$name, $args);
		}
	}
}

$a = new js_object;

//add properties
$a->song = 'Ring a Roses';

$a->sing = function() use(&$a)
{
	echo $a->song;
};

$a->sing();  //Output Ring a Roses

$b = clone $a;

$b->sing = function() use(&$b)
{
	echo 'I am a clone';
};

$b->sing();
Last Updated On : 21st July 2012

Subscribe to get updates delivered to your inbox

  • radmen

    It would be nice if __call was passing $self (as the reference to $this) as a first argument (exactly like in class definitions in Python).

    I’ve done something like this, You can check it on my Github: https://github.com/radmen/ProtoClass/blob/master/ProtoClass.php

    • Silver Moon

      yes, thats a good idea.

  • Michael

    I believe you mean PHP 5.4

    • Silver Moon

      the same would work in php 5.3 as well, just the array declaration syntax needs to be changed.

  • http://www.avantwebconsulting.com Josh

    Array literal syntax does not work in php 5.3

    supermac:~ Josh$ php -v
    PHP 5.3.13 with Suhosin-Patch (cli) (built: Jun 20 2012 17:05:20)
    Copyright (c) 1997-2012 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

    supermac:~ Josh$ php -r ‘$a = ["h" => "i"];’

    Parse error: parse error in Command line code on line 1

    • Silver Moon

      you need php 5.4 or change the array syntax from [...] to array(…)

  • http://www.rommelxcastro.com Rommel Castro A

    cool article, thanks!

  • Spudley

    You say “The object literals are singletons. They cannot be copied and since their is no class”.

    Would it not be possible to use PHP’s “clone” keyword for this?

    Just a thought. :-)

    • Silver Moon

      clone can be used when creating objects with a class, like js_object.
      clone cannot be used with arrays.

1 Flares Twitter 0 Facebook 0 Google+ 1 LinkedIn 0 StumbleUpon 0 Filament.io 1 Flares ×