2012-07-20 104 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(對象本身),以鏈的多個方法在一行中調用。