使用可调用服务管理器的Wierd行为


Wierd behaviour using a service manager invokable

我仍在学习理解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个元素,其中的对象类型为硬件''模型''硬件,但包含最后一个$hardwares元素的数据(也就是说,它在循环时用数据覆盖所有类)

结果:

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"
    }

从服务经理快速启动

shared,一个服务名称/布尔值对的数组,指示是否应该共享服务。默认情况下,ServiceManager假定所有服务都是共享的,但您可以在此处指定布尔值false,以指示应返回新实例。

所以你可能需要做这样的事情。。。

//In module.php getServiceConfig()
return array(
    'invokables' => array(
        'hardwareEntity'        => 'Hardware'Model'Hardware',
    ),
    'shared' => array(
         'hardwareEntity' => false,
    ),
}