Matías Cánepa
Matías Cánepa

Reputation: 5974

how to create objects dynamically in php

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

Answers (2)

Spyric
Spyric

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

alganet
alganet

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

Related Questions