Author: Chris Jeffries
Viewers: 1,360
Last month viewers: 6
Package: dynClass
Read this article to learn why I have written the dynClass extending the stdClass to provide better dynamic features.
What is stdClass?
PHP supports object oriented programming since many years ago in PHP 3. This means that you can create objects of classes that share common variables and functions.
stdClass is a generic class introduced in PHP 4 to create generic objects without any initial variables. You just create an object of the class and set properties on demand.
$object = new stdClass
$object->a = 1;
$object->b = "a";
Why stdClass is not enough?
I have built a static HTML template resolver that would replace tokens by pre-computed values. The pre-computed values were passed in an object of stdClass, where the keys represented property names and the values were the replacement values for the respective tokens.
However, this can be inefficient since all the properties have to be prepared just in case they are used (present in the template).
Introduction to dynClass
What I needed was a way to create late-binding properties which would thus resolve themselves only if needed.Lambda functions seemed the way to go, but I found that although you can add a lambda function as a property to stdClass objects, they remain properties, not methods.
dynClass extends stdClass so that lambda functions are treated as methods of the class. They are full members of the class which means that you can, for example, refer to $this within them.
Now I have a framework that is much more efficient and a class that potentially has other uses too.
dynClass versus stdClass
Better than telling is showing a real example os usage comparing the what you can do with dynClass and not with stdClass.
Initialising classes
$dyn = new dynClass( array( "z"=>"foo", "method1"=>function() { return "Method1 called"; } )); $std = new stdClass(array( "z"=>"foo" ));
dynClass understands initialization from array...
echo "dyn ->z : " . $dyn->z;
... but stdClass does not.
echo "std ->z : " . $std->z;
$dyn->a = array(1,2,3,4,"ttt"); $std->a = array(1,2,3,4,"ttt"); $dyn->b = true; $std->b = true; $dyn->c = "string"; $std->c = "string"; $testclass = new stdClass(); $testclass->property = "test property"; $dyn->o = $testclass; $std->o = $testclass; $dyn->f = function($parm='no value passed') { return "lambda passed $parm"; }; $std->f = function($parm='no value passed') { return "lambda passed $parm"; }; $u = function($parm='no value passed') { return "Saved lambda returned $parm"; }; $dyn->u = $u; $std->u = $u; $t = function($parm='z') { return $this->$parm; }; $dyn->t = $t; global $glob; $glob = "This is a global"; $g = function () { global $glob; return "This is from outside: $glob"; }; $dyn->g = $g; $std->g = $g; $dyn->i = 55; $std->i = 55; $dyn->e = 55E6; $std->e = 55E6;
Var_dump of stdClass
var_dump($std);
Var_dump of dynClass
var_dump($dyn);
Test lambdas added to dynClass as properties directly assigned lambda.
echo "f : {$dyn->f} indirectly assigned lambda u : {$dyn->u} lambda referencing global g : {$dyn->g} lambda referencing \$this t : {$dyn->t} lambda at instantiation method1: {$dyn->method1}";
Test lambdas added to dynClass as methods directly assigned lambda f.
echo "{$dyn->f("-value-")} indirectly assigned lambda u : {$dyn->u("-value-")} lambda referencing global g : {$dyn->g("-value-")} lambda referencing \$this t : {$dyn->t("z")}
The remainder are going to fail.
try {
Test lambdas added to stdClass as properties.
echo "f : {$std->f} u : {$std->u} g : {$std->g}";
Test lambdas added to stdClass as methods.
echo "f : {$std->f("-value-")} u : {$std->u("-value-")} g : {$std->g("-value-")} </pre>"; } catch (Exception $e) {
As anticipated, this error occurred.
}
You need to be a registered user or login to post a comment
Login Immediately with your account on:
Comments:
1. Interesting but misguided attempt - Oded Arbel (2017-04-12 15:07)
Syntactic sugar can cause cancer of the semicolon... - 1 reply
Read the whole comment and replies