Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在ZF2中执行手动编写的查询或存储过程_Php_Sql Server_Zend Framework2 - Fatal编程技术网

Php 如何在ZF2中执行手动编写的查询或存储过程

Php 如何在ZF2中执行手动编写的查询或存储过程,php,sql-server,zend-framework2,Php,Sql Server,Zend Framework2,我在上学习教程,我已经设置了我的Module::getServiceConfig()和我的AlbumTable类,如图所示 现在假设我需要执行一个存储过程来获取结果集…而不是标准的SELECT。我仍然希望结果集是相册模型的集合。如何做到这一点 下面是我尝试过的一个例子: AlbumTable.php: public function findByArtist($artist) { $adapter = $this->tableGateway->getAdapter();

我在上学习教程,我已经设置了我的
Module::getServiceConfig()
和我的
AlbumTable
类,如图所示

现在假设我需要执行一个存储过程来获取结果集…而不是标准的
SELECT
。我仍然希望结果集是
相册
模型的集合。如何做到这一点

下面是我尝试过的一个例子:

AlbumTable.php:

public function findByArtist($artist) {
    $adapter = $this->tableGateway->getAdapter();
    $result = $adapter->query(
        "EXEC spGetAlbums @artist = :artist",
        array(':artist' => $artist)
    );

    var_dump($result->current());
}
问题是返回的
$result
ArrayObject
s的集合,而不是
Album
模型的集合。那么,如何执行存储过程,但仍然根据在
模块::getServiceConfig()中设置的内容获取结果呢


请不要费心问我的存储过程在做什么……这与这个问题无关。关键是,它返回的结果与相册
模型兼容。
^不是态度,只是试图节省每个人的时间,让他们认为我不需要使用存储过程。

正如@Sam在问题注释中建议的那样,似乎没有办法在
TableGateway
对象上执行本机SQL查询,因此您必须手动创建数据对象

在查看Zend的文档之后,我想到了以下解决方案:

namespace Album\Table;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Stdlib\Hydrator;

class Album {

    protected $tableGateway;

    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
    }

    public function findByArtist($artist) {
        $adapter = $this->tableGateway->getAdapter();
        $result = $adapter->query(
            "EXEC spGetAlbums @artist = :artist",
            array(':artist' => $artist)
        );

        $dataSource = $result->getDataSource();
        if ($dataSource instanceof \Iterator) {
            $result = new HydratingResultSet(
                new Hydrator\ArraySerializable(),
                new \Album\Model\Album()
            );
            $result->initialize($dataSource);
        }

        return $result;
    }
}

更新:

public function findByArtist($artist) {
    $adapter = $this->tableGateway->getAdapter();
    $result = $adapter->query(
        "EXEC spGetAlbums @artist = :artist",
        array(':artist' => $artist)
    );

    var_dump($result->current());
}
我并没有真正了解
ReflectionHydrator
到底发生了什么。它是通过反射来填充我的对象,而不是调用我的
exchangeArray()
方法。当我在
exchangearlay()
方法中将数据库中的
smalldatetime
值转换为
\DateTime
对象时,我意识到了这一点……它没有被调用

解决方法是使用
arrayserizable
or。所以我更新了上面的代码来演示这一点

如果您希望hydrator使用您的setter(如
setArtist()
setTitle()
),您可以使用
ClassMethods
hydrator


如果您的属性是公共的(或者如果您使用的是magic
\uu set()
方法),您可以使用
ObjectProperty
水合器,它只会将值分配给您的属性。

您需要手动将ArrayObject水合为Album对象。因为您正在执行本机SQL查询,所以没有其他神奇的事情发生;)没有办法在
TableGateway
对象上执行本机SQL查询吗?回答得好;)
HydratingResultSet
的第一个参数可以更改为其他可能的hydrator,如
classmethodshhydrator
或您自己的hydratorhydrator@Sam:我花了一段时间才意识到水合器之间的区别,但我最终找到了答案,并用更多信息更新了我的答案,希望对其他人有所帮助。