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:我花了一段时间才意识到水合器之间的区别,但我最终找到了答案,并用更多信息更新了我的答案,希望对其他人有所帮助。