views:

49

answers:

2

how to get a class constructor function name without instantiating the class?

example:

$class = 'someClass';
$constructor = somehow get constructor;

$args = array();
$object = call_user_func_array(array($class,$constructor),$args);

what I need is to create a object by passing a undetermined number of variables into it's constructor.

A: 

The function name of the constructor in PHP is always __construct, so you have it already without having to do anything.

Krevan
what about if the class has a constructor of its own class name?
YuriKolovsky
@Yuri: what do you mean? The constructor's name will always be `__construct`, but in order to call it you do `new ClassName();`.
Krevan
@NullUserException oh, I did not know that.@Krevan So i can always without exception do this?call_user_func_array(array($class,'__construct'), $args);
YuriKolovsky
@NullUserException: No it hasn't. It was removed from PHP 5.3.3, but only in namespaces. Outside namespaces the ClassName() form of constructor will still work.
Mewp
No, because `__construct` is not declared static. The only way to do it is to call `new` or to use the `ReflectionClass` class...
ircmaxell
@Mewp Good to know
NullUserException
@Yuri It's been removed in 5.3.3. I don't think it's a good idea at this point in time to write code that assumes it's going to run in 5.3.3 or greater. Of course, a class with a constructor not named `__construct` will not run correctly in 5.3.3 so such code will definitely have bigger problems to deal with.
Jon
@Jon, legacy code... legacy code...
YuriKolovsky
Oops, sorry, my comment above is an answer to Krevan, not Yuri... :-)
Jon
@Jon: Again, it has not been removed. Read http://www.php.net/archive/2010.php#id2010-07-22-2 , quoting: "This change doesn't affect non-namespaced classes."
Mewp
+6  A: 

You can do this with Reflection:

<?php

class Pants
{
    public function __construct($a, $b, $c)
    {
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }
}

$className = 'pants';
$class = new ReflectionClass($className);
$obj = $class->newInstanceArgs(array(1, 2, 3));
var_dump($obj);

This will also work if your constructor uses the old style (unless your code makes use of namespaces and you are using PHP 5.3.3 or, presumably, greater, as old-style constructors will no longer work with namespaced code - more info):

<?php
class Pants {
    function Pants($a, $b, $c) { ... }
}

If the class has no constructor and you wish to use reflection, use $class->newInstance() instead of $class->newInstanceArgs(...). To do this dynamically, it would look like this:

$object = null === $class->getConstructor() 
    ? $class->newInstance()
    : $class->newInstanceArgs($args)
;
Shabbyrobe
what if the class in question does not have a constructor??
YuriKolovsky
found the solution: $object = null === $class->getConstructor() ? $class->newInstance() : $class->newInstanceArgs(array(1, 2, 3));
YuriKolovsky
Sorry, I was out and missed your comment. I'll add it to the answer for the sake of completeness.
Shabbyrobe
*(sidenote)* [As of PHP5.3.3 old style constructors will no longer work when used in conjunction with namespaces](http://www.php.net/archive/2010.php#id2010-07-22-2).
Gordon
Oh, thanks Gordon. I didn't know that. I'll update the answer - it's probably a good idea to make sure that a potentially breaking change like that gets as much visibility as possible.
Shabbyrobe