Javascript style object literals in PHP
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();
Related Posts
-
radmen
-
Michael
-
http://www.avantwebconsulting.com Josh
-
http://www.rommelxcastro.com Rommel Castro A
-
Spudley