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

时间:2013-02-04 16:34:20

标签: php zend-framework2

我仍在学习理解ZF2和imho,最好的办法是做事。我遇到了这个奇怪的问题,并想知道这是否是预期的行为。

在我的应用程序中,我有以下代码

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

在我的控制器中,我从一个文本blob中检索数据,这会产生一个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个元素,其中包含类型为Hardware \ Model \ Hardware的对象,但是包含最后$ 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"
    }

1 个答案:

答案 0 :(得分:1)

来自service manager quick start

  

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

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

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