Reputation: 5974
I have a Class X from where I access the rest of the classes of my application. This access is done dynamically. Sample code below (demo here):
<?
class ClassX
{
var $ClassA;
var $ClassB;
function __construct()
{
$this->ClassA = new ClassA();
$this->ClassB = new ClassB();
}
}
class ClassA
{
function methodA($param)
{
echo $param;
}
}
class ClassB
{
function methodB($param)
{
echo $param + 1;
}
}
/*I can do this for class A*/
$class = "ClassA";
$method = "methodA";
$param = array("some text");
/*or this for class B*/
//$class = "ClassB";
//$method = "methodB";
//$param = array(5);
$objX = new ClassX();
$chain = $objX->{$class};
call_user_func_array(array($chain, $method), $param);
?>
I was thinking if I could go a little further and get rid of the explicit object instances inside X.
In the code above I'm "stuck" with A and B.
I'm looking for a way to build an application that loads different modules but without knowing which modules will be loaded at first hand. So if tomorrow I have a C module, I don't have to change X. The same applies if I no longer support B.
I've tried something like this in X:
function __get($object)
{
$this->$object = new $object();
}
but then I get an invalid callback error, so I guess call_user_func_array is off the table
It's possible to do what I'm trying to achieve?
SOLUTION:
Spyric nailed it! I only needed a return in the __get()
function __get($object)
{
$this->$object = new $object();
return $this->$object;
}
final code here
Upvotes: 1
Views: 447
Reputation: 161
In the past I need something similar to storage data. Code looks lite this:
class ClassX
{
var classes = array();
function __construct()
{
}
}
And getter:
function __get($object)
{
if(!isset($this->classes[$object]))
$this->classes[$object] = new $object();
return $this->classes[$object];
}
UPD: After that you can use
$class = "ClassC";
$method = "methodA";
$param = array("some text");
$objX = new ClassX();
$chain = $objX->{$class};
and $chain will have object from ClassC
If you don't need to reset value of object for each call $objX->{$class}
remove if(!isset($this->classes[object]))
Upvotes: 2
Reputation: 2547
Seems that you need to build these objects dynamically. Try the Reflection extension, here is a sample:
$dateTimeRefl = new ReflectionClass('DateTime');
$dynamicallyBuildDateTime = $dateTimeRefl->newInstance('2013-01-01');
There are two methods: newInstance() and newInstanceArgs(), and they're equivalent to call_user_func() and call_user_func_array().
You'll need PHP 5.2 or newer for this.
Upvotes: 0