2009-02-10 120 views
109

我知道这个问题听起来相当含糊,所以我会让它用一个例子更加清晰:从PHP中的变量实例化类?

$var = 'bar'; 
$bar = new {$var}Class('var for __construct()'); //$bar = new barClass('var for __construct()'); 

这是我想做的事情。你会怎么做?我可以像这样使用eval():

$var = 'bar'; 
eval('$bar = new '.$var.'Class(\'var for __construct()\');'); 

但是我宁愿远离eval()。有没有办法做到这一点没有eval()?

回答

160

把类名到一个变量第一:

$classname=$var.'Class'; 

$bar=new $classname("xyz"); 

这往往是那种你会在一个工厂模式看包裹起来的东西。

查看Namespaces and dynamic language features了解更多详情。

+2

这就是我该怎么做的。请注意,从内部类可以使用父母和自我。 – Ross 2009-02-10 20:55:14

+0

非常感谢。 – 2009-02-10 20:57:06

+1

在类似的笔记上,你也可以做$ var ='Name'; $ OBJ - > { '得到'。是$ var}(); – Mario 2009-02-10 21:04:51

25
class Test { 
    public function yo() { 
     return 'yoes'; 
    } 
} 

$var = 'Test'; 

$obj = new $var(); 
echo $obj->yo(); //yoes 
57

如何通过动态构造函数的参数也

如果要动态构造函数的参数传递给类,您可以使用此代码:

$reflectionClass = new ReflectionClass($className); 

$module = $reflectionClass->newInstanceArgs($arrayOfConstructorParameters); 

More information on dynamic classes and parameters

PHP> = 5.6

从PHP 5.6起,您可以简化件更更使用Argument Unpacking

// The "..." is part of the language and indicates an argument array to unpack. 
$module = new $className(...$arrayOfConstructorParameters); 

感谢DisgruntledGoat指出了这一点。

43

如果您使用的命名空间

在我自己的调查结果,我认为这是很好的一提的是你(据我可以告诉)必须声明一个类的完整的命名空间路径。

MyClass.php

namespace com\company\lib; 
class MyClass { 
} 

的index.php

namespace com\company\lib; 

//Works fine 
$i = new MyClass(); 

$cname = 'MyClass'; 

//Errors 
//$i = new $cname; 

//Works fine 
$cname = "com\\company\\lib\\".$cname; 
$i = new $cname; 
-1

我会建议call_user_func()call_user_func_array PHP方法。 你可以在这里查看(call_user_func_arraycall_user_func)。

例如

class Foo { 
static public function test() { 
    print "Hello world!\n"; 
} 
} 

call_user_func('Foo::test');//FOO is the class, test is the method both separated by :: 
//or 
call_user_func(array('Foo', 'test'));//alternatively you can pass the class and method as an array 

如果你有要传递到方法参数,然后使用call_user_func_array()功能。

示例。

class foo { 
function bar($arg, $arg2) { 
    echo __METHOD__, " got $arg and $arg2\n"; 
} 
} 

// Call the $foo->bar() method with 2 arguments 
call_user_func_array(array("foo", "bar"), array("three", "four")); 
//or 
//FOO is the class, bar is the method both separated by :: 
call_user_func_array("foo::bar"), array("three", "four"));