Zend Framework 2 - 同一服务的多个实例

时间:2015-06-15 07:00:41

标签: php zend-framework

我有一个从db读取的服务,接受SQL查询的参数,我需要为参数的不同值调用它,但是在同一个视图中。实际上,这会导致始终使用最后一个值调用它。 示例(这在我的控制器中):

public function someAction () {
        return new ViewModel(array (
            "welcome" => $this->homeService->findText("welcome"),
            "address" => $this->homeService->findText("address"),
            "map" => $this->homeService->findText("map"),
    ));
}

这样做会调用我的homeService,因为它的参数是" map"一直以来。

我试着在我的module.config.php中设置它(Site \ Service \ HomeServiceInterface当然是我的homeService):

'service_manager' => array(
    'factories' => array(
        'Site\Service\HomeServiceInterface' => 'Site\Factory\HomeServiceFactory',
    ),
    'shared' => array (
        'Site\Service\HomeServiceInterface' => false
    ),
),

因为我读过“分享”#39;数组应该允许具有相同服务的多个实例,但这并不起作用。所以,除了创造另一项服务(我觉得很糟糕),我无法想象如何去做。有任何想法吗?谢谢。

修改

HomeService(界面包含所需的一切)

use Site\Model\Home;
use Site\Model\HomeInterface;
use Site\Mapper\TextMapperInterface;


class HomeService implements HomeServiceInterface {
    protected $textMapper;

    public function __construct (TextMapperInterface $textMapper) {
        $this->textMapper = $textMapper;
    }
    public function findText($name) {
        return $this->textMapper->find($name);
    }
}

TextMapper如下:

use Site\Model\HomeInterface;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Stdlib\Hydrator\HydratorInterface;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\Sql\Sql;
use Zend\Stdlib\Hydrator\ClassMethods;

class TextMapper implements TextMapperInterface {
    protected $homePrototype;
    protected $adapter;
    protected $hydrator;

    public function __construct(AdapterInterface $adapter, HomeInterface $homePrototype, HydratorInterface $hydrator) {
        $this->adapter = $adapter;
        $this->homePrototype = $homePrototype;
        $this->hydrator = $hydrator;
    }

    public function find($name) {
        $sql = new Sql($this->adapter);
        $select = $sql->select();
        $select->from("mono");
        $select->where(array("name = ?" => $name));
        $stmt = $sql->prepareStatementForSqlObject($select);
        $result = $stmt->execute();

        if ($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()) {
            return $this->hydrator->hydrate($result->current(), $this->homePrototype);
        }

        throw new \InvalidArgumentException("{$name} doesn't exist.");
    }
}

HomeInterface是模型,它只有getter和setter方法。

1 个答案:

答案 0 :(得分:0)

好吧,我想我已经解决了,所以我发布了我的想法,这肯定是正常的。 当然,textMapper只能由__construct ()实例化一次,所以我想它每次在同一个动作中调用时都会以相同的方式发生。我决定修改一切。我有一个包含3行的数据库:idname(我现在在我的find($name)函数中使用它)和text。 我的模型看起来像这样:

class Home implements HomeInterface {
    protected $id;
    protected $name;
    protected $text;


    public function getId() {
        return $this->id;
    }

    public function setId($id) {
        $this->id = $id;
    }

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getText() {
        return $this->text;
    }

    public function setText ($text) {
        $this->text = $text;
    }
}

现在我更改了表:字段为idhomecertificationaboutwelcomeaddress,{{1 (最后3个是我在这种情况下需要的)。所以现在我的新map有了新的getter和setter来适应这种新方式。 (HomegetHome()等...) Mapper' setHome($home)不再需要find()参数。现在我可以在视图中使用我需要的getter来显示我想要的文本。我现在的行动很简单:

$name

并在some.phtml页面中:

public function someAction () {
    return new ViewModel(array (
        "welcome" => $this->homeService->findText("welcome"),
    ));
}

我认为这是一个比以前更好的设计。