Page 1 of 1

Dynamic Class Instantiation with Variable Parameter Count

Posted: Sun Sep 24, 2006 1:43 pm
by Ollie Saunders
I want to create a function that can create an instance of any class with any number of parameters.

This code gives me Fatal error: Non-static method Box::__construct() cannot be called statically. Any idea how I do this?

Code: Select all

class Object
{
    protected $_area;
    public function getArea()
    {
        return $_area;
    }
}
class Box extends Object
{
    public function __construct($x, $y, $z)
    {
        $this->_area = $x * $y * $z;
    }
}
class Square extends Object
{
    public function __construct($x, $y)
    {
        $this->_area = $x * $y;
    }
}

function createClass($name, $constructionParams)
{
    return call_user_func_array(array($name, '__construct'), $constructionParams);
}

$a = createClass('Box', array(1, 2, 3));
echo $a->getArea();

$b = createClass('Square', array(4, 6));
echo $b->getArea();
Otherwise, it'll be eval I guess.

Please don't post guesses without trying them first.
Thanks.

Posted: Sun Sep 24, 2006 1:49 pm
by feyd
We've had this discussion fairly recently. Check in Theory and Design. Specifically look for volka's more recent posts.

Posted: Sun Sep 24, 2006 1:57 pm
by Ollie Saunders
Searched for posts by Volka in T&D and found less than two complete pages none of which were relevent. Plenty on __get and __set accessors.

Posted: Sun Sep 24, 2006 2:00 pm
by feyd
It may have been in Testing...

Posted: Sun Sep 24, 2006 2:11 pm
by Ollie Saunders
Nope, volka's only posts were in a thread I created.

Posted: Sun Sep 24, 2006 2:16 pm
by Luke

Posted: Sun Sep 24, 2006 2:20 pm
by Jenk
Note to use newInstanceArgs() you'll need version >= php5.1.3

Posted: Sun Sep 24, 2006 2:24 pm
by Ollie Saunders
Thanks everyone

Posted: Sun Sep 24, 2006 2:29 pm
by Ollie Saunders
Here's the complete code I went for:

Code: Select all

class Object
{
    protected $_area;
    public function getArea()
    {
        return $this->_area . ' ';
    }
}
class Box extends Object
{
    public function __construct($x, $y, $z)
    {
        $this->_area = $x * $y * $z;
    }
}
class Square extends Object
{
    public function __construct($x, $y)
    {
        $this->_area = $x * $y;
    }
}

function createClass()
{
    $params = func_get_args();
    $name = array_shift($params);

    if (version_compare(PHP_VERSION, '5.1.3') >= 0) {
        $reflection = new ReflectionClass($name);
        return $reflection->newInstanceArgs($params);
    }
    $params = array_map(create_function('$a', 'return var_export($a, true);'), $params);
    $evalStr = 'return new $name(' . implode(',', $params) . ');';
    return eval($evalStr);
}

$a = createClass('Box', 1, 2, 3);
echo $a->getArea();

$b = createClass('Square', 4, 6);
echo $b->getArea();