views:

227

answers:

7

I need to pass a variable number of strings to instantiate different classes. I can always do a switch on the size of the array:

switch(count($a)) {
case 1:
    new Class(${$a[0]});
    break;
case 2:
    new Class(${$a[0]}, ${$a[1]});
    break;
etc...

There has to be a better way to do this. If I have an array of strings ("variable1", "variable2", 'variable3", ...), how can I instantiate a Class without manually accounting for every possibility?

+1  A: 
<?php

new Example($array);

class Example
{
    public function __construct()
    {
        foreach (func_get_args() as $arg)
        {
            // do stuff
        }
    }
}
Coronatus
Why is this downvoted?
Coronatus
-100, it won't do it, that is not what OP is looking for.
Seems to me it is.
Coronatus
This is exactly what the OP asked for! Coronatus could have demonstrated it with a better "new Example" line (rather than using an array, it can also except a series of variables just as requested). There is a performance benefit to using this approach over the accepted Reflection solution (for now - it's a moving target ;))eg. $n=new Example("var 1","var 2");
Rudu
A: 

Look here. Does method 2 help ? Also, perhaps by moving the switch to the constructor (if that is practical) you would be able to hide this from the rest of the code.

nc3b
A: 

You can use an array to pass variable number of variable to the class, for example:

<?php

class test
{
  private $myarray = array();

  function save($index, $value)
  {
      $this->myarray[$index] = $value;
  }

  function get($index)
  {
     echo $this->myarray[$index] . '<br />';
  }
}

$test = new test;
$test->save('1', 'some value here 1');
$test->save('2', 'some value here 2');
$test->save('3', 'some value here 3');

$test->get(1);
$test->get(2);
$test->get(3);

 ?>

Output

some value here 1
some value here 2
some value here 3

You could also use the __get and __set magic methods to save info easily.

Sarfraz
why down vote??????????????????????????
Sarfraz
I don't think the question was asking how to make setters and getters...
Lotus Notes
@byronh: You can use setter and getter also to set variable number of info to the class for later retrieval easily.
Sarfraz
I guess you're right. Sometimes it's hard deciding whether to directly answer a question that has a design flaw or simply suggesting an easier alternative.
Lotus Notes
+1: dodging the question with a BETTER solution is always good. Using arrays is so much simpler and php-ish.
Lo'oris
And what if the class does not allow passing in an array but requires specfic arguments? or when it is not open for modification like show above? Sometimes you might not want to allow setters for classes, e.g. when you need immutable members. Reflection is the better solution imho.
Gordon
+1  A: 
// Constructs an instance of a class with a variable number of parameters.

function make() { // Params: classname, list of constructor params
 $args = func_get_args();
 $classname = array_shift($args);
 $reflection = new ReflectionClass($classname);
 return $reflection->newInstanceArgs($args);
}

How to use:

$MyClass = make('MyClass', $string1, $string2, $string3);

Edit: if you want to use this function with your $a = array("variable1", "variable2", 'variable3", ...)

call_user_func_array('make', array_merge(array('MyClass'), $a));
Lotus Notes
A: 

It seems that reflection can pull this one out of the hat for you. This comes to you courtesy of the PHP call_user_func_array notes. The following code will create a class by calling the constructor with the contents of your array.

<?php
// arguments you wish to pass to constructor of new object
$args = array('a', 'b');

// class name of new object
$className = 'ClassName';

// make a reflection object
$reflectionObj = new ReflectionClass($className);

// use Reflection to create a new instance, using the $args
$command = $reflectionObj->newInstanceArgs($args);
// this is the same as: new myCommand('a', 'b');

?>
El Yobo
+3  A: 

If you must do it this way, you can try:

$variable1 = 1;
$variable2 = 2;
$variable3 = 3;
$variable4 = 4;

$varNames = array('variable1', 'variable2', 'variable3', 'variable4');
$reflection = new ReflectionClass('A');
$myObject = $reflection->newInstanceArgs(compact($varNames)); 

class A
{
    function A()
    {
        print_r(func_get_args());
    }
}
webbiedave
Ah - that's very interesting. That is exactly what I was looking for. Thanks to everyone for their help!
You're welcome. Glad I could help.
webbiedave
A: 

have a look at the factory design pattern:

class Factory {
  public static function CreateInstance($args) {
    switch(func_get_num_args()) {
      case …:
        return new ClassA(…); break;
      case …:
        return new ClassB(…); break;
    }
  }
}
knittl