ZF2如何获取最后插入的ID值?

18

我在使用Zend Framework 2时遇到了获取最后插入ID的问题,但是我已经放弃了...

这是我尝试过的组合:

var_dump($this->tableGateway->insert($insert));
var_dump($this->tableGateway->lastInsertValue);
var_dump($this->tableGateway->getLastInsertValue());
var_dump($this->tableGateway->getAdapter()->getDriver()->getConnection()->getLastGeneratedValue());

值已插入到表中,但每一行(除第一行外,它返回int“1”)都返回null。请不要告诉我,这样一个大框架不提供获取最后插入id值的可能性!?


尝试使用 $this->tableGateway->getAdapter()->lastInsertId(); - phpisuber01
2
$adapter->getDriver()->getLastGeneratedValue(); $adapter->获取驱动程序()->获取最后生成的值(); - chandresh_cool
2
您还可以为序列对象提供名称:$adapter->getDriver()->getLastGeneratedValue($name) - kingdaemon
致命错误:调用未定义的方法Zend\Db\Adapter\Adapter::getConnection()。 - Piotr
1
@Piotr 这是来自 PHP 手册的内容:"PDO_PGSQL() 要求您为 name 参数指定序列对象的名称。" 我猜对于其他驱动程序,您可以从 TableGateway 中调用 getLastInsertValue()。 - kingdaemon
显示剩余7条评论
7个回答

28

这是我使用的:

$data = array()// Your data to be saved;
$this->tableGateway->insert($data);
$id = $this->tableGateway->lastInsertValue;

10

我知道这已经过去一段时间了,但在花费大量时间解决这个特定问题后,我想发布解决方案,以帮助未来遇到相同问题的网友。

问题出在Pgsql数据库驱动程序需要指定一个序列名称才能返回最后一个id,如下所示:

$adapter->getDriver()->getLastGeneratedValue("sequence_name");

这在2.3.1版本中有效。在2.2.2版本(以及可能之后的版本)中存在一个错误,即“name”不是驱动程序中getLastGeneratedValue的参数,因此您必须直接调用连接。

$adapter->getDriver()->getConnection()->getLastGeneratedValue

所以这就是我通过查看代码发现的。最好的解决方案是确保你的ZF2已经更新,并且使用

$adapter->getDriver()->getLastGeneratedValue("sequence_name");

2
这是我能找到的唯一解决方案,而且它对我有效。 - Programmer
这对我也起作用了 :) 如果你想知道如何找到默认的 sequence_name,可以尝试这样做:<table_name>_<primaryKey>_seq。例如:customers_id_seq - John Skoumbourdis
在ZF3中,使用驱动程序“Pdo_Pgsql”,只有您的最后一个解决方案有效。 - bitkorn

4
在PostgreSQL中,您需要设置SequenceFeature:
...
use Zend\Db\TableGateway\Feature;
...
public function setDbAdapter( Adapter $adapter ) {
   ...
   $this->featureSet = new Feature\FeatureSet();
   $this->featureSet->addFeature(new Feature\SequenceFeature('YOUR_FIELD_NAME','YOUR_SEQUENCE_NAME'));
   $this->initialize();
}

现在,$this->tableGateway->getLastInsertValue(); 应该可以正常工作了。

《Zend Framework 2.0 by example beginners guide》一书指出,getLastInsertValue()函数返回表主键的最后插入值。返回类型为整数。 - Julian

3

好的,我知道这个问题已经几个月了,但对于那些正在寻找解决此问题的人来说,获取最后插入的值的最佳方法是从适配器接口中获取该值。

do your insert //then
$id = $adapter->getDriver()->getLastGeneratedValue();

我对MySQL数据库的这种处理方式很有效


最佳答案+1,我也会给你的其他回答点赞。 - user285594

1
在扩展了AbstractTableGatewayApp\Model\AlbumTable中,我通过$inserted_id = $this->lastInsertValue;获取最后一个id。
例如:
 if ($id == 0) {
            $this->insert($data);
            $inserted_id = $this->lastInsertValue;    
        } elseif ($this->getAlbum($id)) {
            $this->update(
                $data, array(
                'id' => $id,
                )
            );
        } else {
            throw new \Exception('Form id does not exist');
        }

0

0

有另一种可能性可以将FeatureSet添加到TableGateway中。

在Module.php中,您可以定义(例如,User表)

            'UserTableGateway' => function ($sm) {
                $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new UserEntity());
                return new TableGateway('user', $dbAdapter, new Feature\SequenceFeature('user','user_id_seq'), $resultSetPrototype);

但是SequenceFeature存在一个bug。当您使用公共模式时,一切正常。当您需要使用其他模式时,应该使用Zend\Db\Sql\TableIdentifier;

在这种情况下,Module.php应该是:

            'UserTableGateway' => function ($sm) {
                $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new UserEntity());
                return new TableGateway(new TableIdentifier('user','someSchema'), $dbAdapter, new Feature\SequenceFeature(new TableIdentifier('user','someSchema'),'user_id_seq'), $resultSetPrototype);

在这种情况下,使用Postgresql查询SELECT NEXTVAL时会出现错误,因为Feature\SequenceFeature将使用公共模式而不是在第一个参数中定义的模式来准备查询。
SELECT NEXTVAL('user_id_seq')
在这种情况下,SQL查询应该是
SELECT NEXTVAL('someSchema'.'user_id_seq')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接