cakephp: QueryBuilder - lastInsertId() returns "0"
This is a (multiple allowed):
-
bug
-
enhancement
-
feature-discussion (RFC)
-
CakePHP Version: 3.4.7
-
Platform and Target: MariaDB (5.5.5-10.1.21), PHP Version 7.1.1, Apache, Windows 7
What you did
Trying to insert a new record and get the lastInsertId (AUTO_INCREMENT).
What happened
The result of lastInsertId() is always “0”.
Example code:
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR (255),
PRIMARY KEY (`id`)
) ENGINE = INNODB CHARSET = utf8 COLLATE = utf8_unicode_ci ;
// composer require cakephp/database
require_once __DIR__ . '/vendor/autoload.php';
// Database settings
$config = array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'port' => '3306',
'username' => 'root',
'password' => '',
'database' => 'test',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
);
$driver = new \Cake\Database\Driver\Mysql($config);
$db = new \Cake\Database\Connection(['driver' => $driver]);
$row = [
'username' => 'max'
];
$result = $db->insert('users', $row);
$newId = $result->lastInsertId();
echo $newId; // value is "0"
If I try the same with a native PDO query it works, but not with the CakePHP QueryBuilder.
$pdo = $db->getDriver()->connection();
$stmt = $pdo->query("SELECT LAST_INSERT_ID()");
$lastId = $stmt->fetchColumn(); // This works. Returns 1 or more.
What you expected to happen
Returns the ID of the last inserted row or sequence value.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 18 (18 by maintainers)
Commits related to this issue
- Merge pull request #10839 from odan/patch-1 Fixed Xdebug issue in combination with isConnected() #10836 — committed to cakephp/cakephp by lorenzo 7 years ago
Here is an update:
There is an issue with the magic method: __debugInfo() in Driver.php
https://github.com/cakephp/cakephp/blob/master/src/Database/Driver.php#L386
Xdebug uses PHP’s var_dump() function for displaying variables. https://xdebug.org/docs/display
Changing the
xdebug.overload_var_dumpvalue in php.ini has no positive effect. https://derickrethans.nl/xdebug-2.3-overload-vardump.htmlWorkaround / Fix: If you return just an empty array it works like expected.
This fix also works:
The isConnected method starts a database query (SELECT 1) to check if the connection is available.
https://github.com/cakephp/cakephp/blob/b27ebbd6a4e9b6062bd45e13a439b7ab7f29d0af/src/Database/Driver/PDODriverTrait.php#L92
After every SELECT the lastInsertId() is 0. That’s the reason.
@lorenzo For me this is no more an Xdebug issue. What do you think?
Ok this is crazy… I’ve testet the same code on my home computer and here it works.
But then I enabled a breakpoint and started XDebug and the result is 0 again.
If I remove the debugger breakpoint in PHPStorm (XDebug is still running) everything works! How is that possible?
Connection != null is probably good enough for debug data. I wouldn’t change isConnected() though.
I have stopped using lastInsertId for the same reason. When ever I want to get back the lastInsertedId I always query the database to find the record. It’s too unstable getting the id from lastInsertId and you might easily end up with race conditions.