31

I have a base class called field and classes that extend this class such as text, select, radio, checkbox, date, time, number, etc.

Classes that extend field class are dynamically called in a directory recursively using include_once(). I do this so that I ( and others) can easily add a new field type only by adding a single file

What I want to know: Is there a way to substantiate a new object from one of these dynamically included extending classes from a variable name?

e.g. a class with the name checkbox :

$field_type = 'checkbox';

$field = new {$field_type}();

Maybe this would work? but it does not?

$field_type = 'checkbox';

$field = new $$field_type();
John Slegers
  • 45,213
  • 22
  • 199
  • 169
andrew mclagan
  • 327
  • 1
  • 3
  • 5

7 Answers7

51

This should work to instantiate a class with a string variable value:

$type = 'Checkbox'; 
$field = new $type();
echo get_class($field); // Output: Checkbox

So your code should work I'd imagine. What is your question again?

If you want to make a class that includes all extended classes then that is not possible. That's not how classes work in PHP.

sg3s
  • 9,411
  • 3
  • 36
  • 52
  • I do not want to extend multiple classes, although this would not defeat OOP if it were possible. Some languages actually allow lultiple inheritance – andrew mclagan Aug 20 '11 at 11:05
24

If you are using a namespace you will need to add it even if you are within the namespace.

namespace Foo;

$my_var = '\Foo\Bar';
new $my_var;

Otherwise it will not be able to get the class.

Sam_Benne
  • 595
  • 5
  • 18
  • 3
    You can automatize for PHP >= 5.3 that with the [`__NAMESPACE__` constant](http://php.net/manual/en/language.namespaces.nsconstants.php) : `$my_var = __NAMESPACE__ . '\Bar';`. – Ivan Gabriele Apr 28 '15 at 00:33
6

just

$type = 'checkbox';
$filed = new $type();

is required. you do not need to add brackets

genesis
  • 50,477
  • 20
  • 96
  • 125
1

Spent some time figuring this out. From PHP documentation Namespaces and dynamic language features:

Note that because there is no difference between a qualified and a fully qualified Name inside a dynamic class name, function name, or constant name, the leading backslash is not necessary.

namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "namespaced";

/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // also prints namespacename\classname::__construct

$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // also prints namespacename\funcname

echo constant('\namespacename\constname'), "\n"; // prints namespaced
echo constant('namespacename\constname'), "\n"; // also prints namespaced
zstate
  • 1,995
  • 1
  • 18
  • 20
1

You can also use reflection, $class = new ReflectionClass($class_name); $instance = $class->newInstance(arg1, arg2, ...);

shesek
  • 4,584
  • 1
  • 28
  • 27
0

This should be enough:

$field_type = 'checkbox';
$field = new $field_type();

Code I tested it with in PHP 5.3

$c = 'stdClass';

$a = new $c();

var_dump($a);

>> object(stdClass)#1 (0) {
}
Mchl
  • 61,444
  • 9
  • 118
  • 120
0
$field_type = 'checkbox';
$field = new $field_type;

If you need arguments:

$field_type = 'checkbox';
$field = new $field_type(5,7,$user);
RiaD
  • 46,822
  • 11
  • 79
  • 123