Cranio
Cranio

Reputation: 9848

Creating a dynamic class instance programmatically in PHP with variable arguments?

I've some code that creates ad instance with a dynamic class (i.e. from a variable):

$instance = new $myClass();

Since the constructor has different argument count depending on $myClass value, How do I pass a variable list of arguments to the new statement? Is it possible?

Upvotes: 11

Views: 10755

Answers (3)

Dieter Gribnitz
Dieter Gribnitz

Reputation: 5218

I don't know why but i don't like using the new operator in my code.

Here is a static function to create an instance of a class called statically.

class ClassName {
    public static function init(){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs(func_get_args());        
    }

    public static function initArray($array=[]){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs($array);        
    }

    public function __construct($arg1, $arg2, $arg3){
        ///construction code
    } 
}

If you are using it inside a namespace you need to escape ReflectionClass like so: new \ReflectionClass...

Now you can call the init() method with a variable number of arguments and it will pass it on to the constructor and return an object for you.

Normal way using new

$obj = new ClassName('arg1', 'arg2', 'arg3');
echo $obj->method1()->method2();

Inline way using new

echo (new ClassName('arg1', 'arg2', 'arg3'))->method1()->method2();

Static call using init instead of new

echo ClassName::init('arg1', 'arg2', 'arg3')->method1()->method2();

Static call using initArray instead of new

echo ClassName::initArray(['arg1', 'arg2', 'arg3'])->method1()->method2();

The nice thing about the static methods is that you can run some pre construction operations in the init methods such as constructor argument validation.

Upvotes: 1

Esailija
Esailija

Reputation: 140234

class Horse {
    public function __construct( $a, $b, $c ) {
        echo $a;
        echo $b;
        echo $c;
    }
}

$myClass = "Horse";
$refl = new ReflectionClass($myClass);
$instance = $refl->newInstanceArgs( array(
    "first", "second", "third"    
));
//"firstsecondthird" is echoed

You can also inspect the constructor in the above code:

$constructorRefl = $refl->getMethod( "__construct");

print_r( $constructorRefl->getParameters() );

/*
Array
(
    [0] => ReflectionParameter Object
        (
            [name] => a
        )

    [1] => ReflectionParameter Object
        (
            [name] => b
        )

    [2] => ReflectionParameter Object
        (
            [name] => c
        )

)
*/

Upvotes: 14

Richard Parnaby-King
Richard Parnaby-King

Reputation: 14891

The easiest route would be to use an array.

public function __construct($args = array())
{
  foreach($array as $k => $v)
  {
    if(property_exists('myClass', $k)) // where myClass is your class name.
    {
      $this->{$k} = $v;
    }
  }
}

Upvotes: 0

Related Questions