Dynamic Class Instantiation with Variable Parameter Count

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Dynamic Class Instantiation with Variable Parameter Count

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

We've had this discussion fairly recently. Check in Theory and Design. Specifically look for volka's more recent posts.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

It may have been in Testing...
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Nope, volka's only posts were in a thread I created.
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Note to use newInstanceArgs() you'll need version >= php5.1.3
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Thanks everyone
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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();
Post Reply