2012-07-20 83 views
0

是否有可能从一个字符串实例化一个类,而无需在之前声明另一个变量?php:实例化类动态

它通常写完

$className = 'myClass' 
$instance = new $className(); 

但它可以很方便的把它像短例如

$instance = new ${'className'}(); 

目的是在循环中有没有使用创建的对象(条件下)额外的变量...

编辑: $ className是动态的,它是硬编码以解释情况

+2

PHP 5.3有一些新的语法,所以它可能在那里工作。另一个解决方案是使用'eval'。为什么你有'没有额外的变数'约束? – Halcyon 2012-07-20 19:41:38

+0

另外,如果没有类名的变量,那么你可以直接编写'$ instance = new classname();'。如果您事先知道类名,则可以对其进行硬编码;如果你不这样做,它已经在一个变量中。也许你可以进一步扩展你的问题来更清楚地解释你的需求。 – 2012-07-20 19:43:20

+0

我不明白。如果你没有使用一个变量来动态地改变''className''字符串,为什么你不能''new className()' – tigrang 2012-07-20 19:43:31

回答

1

您可以创建一个将类名作为参数的工厂函数(或类/方法),然后使用生成该字符串的动态PHP代码的结果调用它。你可能会认为它有点干净,但它不会为你节省任何内存或速度。

class foo { } 
function factory($class) { return new $class(); } 

foreach (...) { 
    $instance = factory(<some code that returns the string 'foo'>); 
} 
+0

除了内存使用看起来不是真正的交易外,这个解决方案很有趣......我将这种动态实例化用于不同的方法,所以它可能成为集中管理和更好控制的一种方式。 – anael 2012-07-20 22:59:12

+0

这个例子是错误的。工厂应该是foo中的一个静态方法,并且使用foo实例化新类。看下面的例子... – kodeart 2012-07-21 10:38:58

+0

这当然不是“错误的”。虽然工厂经常作为一个班级来实施(正是我在答案中表明“或班级/方法”的原因),但这样做绝对没有语法或道德要求。 – 2012-07-21 15:46:24

1

这是一个额外的变量,它真的有很大的区别吗?答案是,除非你使用eval(带有安全问题),否则不可能比你的第一个例子短。

2

参见factory pattern

class Foo { 
    static function factory($class, array $args = null) { 
     return new $class($args); 
    } 
} 

// class factoring; returns a new instance of requested class ($className) 
Foo::factory($className); 

我添加了可选参数数组,如果你想设置一些类属性。

// pass some values for class constructor 
Foo::factory($className, array('arg1' => 1, 'arg2' => 2, 'args3' => 3)); 

此外,这样就可以“链”的方法,当您使用图案就可以构建“流体”接口:

Foo::factory($className)->method1()->method2(array('param' => 'value'))->etc(); 

其中method1()method2()必须return $this(对象本身),以链的多个方法在一行中调用。