2013-02-04 64 views
-1

我仍然在學習理解ZF2和imho最好的方式是通過做事情。我遇到了這個奇怪的問題,並想知道這是否是預期的行爲。使用服務管理器調用的奇怪行爲

在我的應用程序有以下代碼

//In module.php getServiceConfig() 
return array(
    'invokables' => array(
     'hardwareEntity'  => 'Hardware\Model\Hardware', 
    ), 
} 
在我的控制器我從文本的斑點,這導致x個元素的陣列中檢索數據,讓我們3爲示例

$hardwares = array(
    'hw1' => array(
     'name' => 'router1' 
     'ip' => '192.168.0.200', 
     'type' => 'router', 
    ), 

    'hw2' => array(
     'name' => 'pc1' 
     'ip' => '192.168.0.210', 
     'type' => 'pc', 
    ), 

    'hw3' => array(
     'name' => 'pc2' 
     'ip' => '192.168.0.211', 
     'type' => 'pc', 
    ), 
); 

我在硬件模塊中有一個硬件類

namespace Hardware\Model\; 
class Hardware 
{ 
    protected $name = null; 
    protected $ip = null; 
    protected $type = null; 

    public function exchangeArray(array $data) { 

     $this->name = (isset($data['name'])) ? $data['name'] : $this->name; 
     $this->ip = (isset($data['ip']))  ? $data['ip'] : $this->ip; 
     $this->type = (isset($data['type'])) ? $data['type'] : $this->type; 
    } 
} 

好神奇的是當我做下面的foreach循環我得到不同的結果

foreach($hardwares as $hw) { 
    $h = $this->getServiceManager()->get('hardwareEntity'); 
    $h->exchangeData($hw); 
    $aObjects[] = $h 
} 

的$ aObjects數組現在包含與硬件\型號\硬件類型的對象3組的元素,但隨着數據最後$硬件元素(又名它覆蓋所有而循環數據類)

結果:

array(3) { 
    [0]=> 
    object(Hardware\Model\Hardware)#219 { 
     ["name":protected]=> 
     string(7) "pc2" 
     ["ip":protected]=> 
     string(13) "192.168.0.211" 
     ["type":protected]=> 
     string(6) "pc" 
    } 
    [1]=> 
    object(Hardware\Model\Hardware)#219 { 
     ["name":protected]=> 
     string(7) "pc2" 
     ["ip":protected]=> 
     string(13) "192.168.0.211" 
     ["type":protected]=> 
     string(6) "pc" 
    } 
    [2]=> 
    object(Hardware\Model\Hardware)#219 { 
     ["name":protected]=> 
     string(7) "pc2" 
     ["ip":protected]=> 
     string(13) "192.168.0.211" 
     ["type":protected]=> 
     string(6) "pc" 
    } 

但是當我做

foreach($hardwares as $hw) { 
    $h = new \Hardware\Model\Hardware(); 
    $h->exchangeData($hw); 
    $aObjects[] = $h 
} 

它使用包含不同數據的新實例化類來填充$ aObjects數組。

結果:

array(3) { 
    [0]=> 
    object(Hardware\Model\Hardware)#219 { 
     ["name":protected]=> 
     string(7) "router1" 
     ["ip":protected]=> 
     string(13) "192.168.0.200" 
     ["type":protected]=> 
     string(6) "router" 
    } 
    [1]=> 
    object(Hardware\Model\Hardware)#220 { 
     ["name":protected]=> 
     string(7) "pc1" 
     ["ip":protected]=> 
     string(13) "192.168.0.210" 
     ["type":protected]=> 
     string(6) "pc" 
    } 
    [2]=> 
    object(Hardware\Model\Hardware)#221 { 
     ["name":protected]=> 
     string(7) "pc2" 
     ["ip":protected]=> 
     string(13) "192.168.0.211" 
     ["type":protected]=> 
     string(6) "pc" 
    } 

回答

1

service manager quick start

共享

,表示服務名稱/布爾對,的陣列的服務是否不應該被共享。默認情況下,ServiceManager假定所有的服務都是共享的,但是你可以在這裏指定一個布爾值false來表示應該返回一個新的實例。

所以,你可能需要做這樣的事情......

該訣竅
//In module.php getServiceConfig() 
return array(
    'invokables' => array(
     'hardwareEntity'  => 'Hardware\Model\Hardware', 
    ), 
    'shared' => array(
     'hardwareEntity' => false, 
    ), 
} 
+0

聖鉬。我仍然對術語感到困惑。但是,謝謝 – Ponsjuh

+0

起初讓我困惑了一下,但基本上服務管理器服務有點像單例,你總是得到相同的實例,除非你明確地告訴它不要共享那個服務實例。當你這樣做時,它的行爲更像是一種工廠方法。 – Crisp