【问题标题】:PDO lastInsertId() always return 0PDO lastInsertId() 总是返回 0
【发布时间】:2012-07-31 09:16:20
【问题描述】:

我遇到了一个问题。我的框架在 PHP 5.3.0 上运行良好。我将我的 PHP 版本升级到 PHP 5.4.x,我的框架的某些部分开始出现一些问题。

PHP版本升级后,PDO lastInsterId()总是返回0

我有一个名为 id 的自动增量字段。 它正在将数据添加到数据库中,没有任何问题。

由于某种原因,我一直将 0 作为最后插入 ID。

这是我的代码;

databaseobjects.php

public static function create () {
        global $db;
        $attributes = self::sanitize(static::$fields);

        $sql  = "INSERT INTO ".PREFIX.static::$table_name." (";
        $sql .= join(", ", array_keys($attributes));
        $sql .= ") VALUE (:";
        $sql .= join(", :", array_keys($attributes));
        $sql .= ")";

        return ($db->crudQuery($sql, $attributes)) ? true : false;
    }

public static function lastInsertID () {
        global $db;
        return $db->handler->lastInsertId();
    }

database.php

public function crudQuery($sql, $data) {
        $sth = $this->handler->prepare($sql);
        return $sth->execute($data);
    }

首先调用create() 方法,然后调用crudQuery() 方法。 正如我之前提到的,我可以成功地将数据添加到 MySQL 数据库中。 不幸的是,当我调用 lastInsterID() 方法时,它总是返回 0。

如果您能在我使用 SQL Query 获得最后一个 ID 之前帮助我解决这个问题,我将非常高兴(:

【问题讨论】:

  • 我注意到您的方法定义中的 static 关键字。 如何调用这些方法?
  • 数据库中的每个表都有一个类(如果表没有类,我的框架会自动创建它们)。每个数据库表类都扩展到databaseobjects.php。这样,我在编码时就不会重复自己。
  • 记住 lastInsertId()connection 而不是 table 独有的 - 您在调用 create()lastInsertID()?另请注意,lastInsertId() 报告 0 如果查询是在事务中执行并且您在 COMMIT 之后查询 id
  • 我已经仔细检查了我的查询,并且在运行 lastInsertID() 方法之前运行了正确的 INSERT 查询。我也试过return $db->handler->lastInsertId('id');,但没有成功。

标签: php pdo lastinsertid


【解决方案1】:

另一个问题可能是使用 $pdo->exec($sql) 而不是 $pdo->query($sql)。

当您使用 $pdo->lastInsertId() 时,

exec($sql) 将始终返回 0。所以请改用 query()。

【讨论】:

    【解决方案2】:

    当没有抛出异常时,lastInsertId 返回 0。但是,如果在调用 commit 之前调用了 lastInsertId,则返回正确的 id。

    http://php.net/manual/es/pdo.lastinsertid.php

    【讨论】:

    • 这正是我的问题所在。我使用您的解决方案解决了它。感谢分享!
    【解决方案3】:

    当最后一个插入语句由于外键约束而失败时,我得到一个 0。 last_error 是一个字符串。

    【讨论】:

      【解决方案4】:

      提交事务后,PDO::lastInsertID() 将返回 0,因此最好在事务提交之前调用此方法。

      【讨论】:

      • 这是正确答案
      【解决方案5】:

      除了 php/PDO 或您的框架中的错误之外,还有两种可能性。 lastInsertId() 是在与插入不同的 MySQL 连接上调用的,或者您正在应用程序/框架中生成 id 并将其插入,而不是让 auto_increment 为您生成它。表中哪一列是主键/auto_increment?该列是否包含在您的 create() 函数中的 $attributes 中?

      您可以测试 PDO 以确保该部分与此代码(在新文件中)正常工作:

      // Replace the database connection information, username and password with your own.
      $conn = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'password');
      
      $conn->exec('CREATE TABLE testIncrement ' .
                  '(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))');
      $sth = $conn->prepare('INSERT INTO testIncrement (name) VALUES (:name)');
      $sth->execute([':name' => 'foo']);
      var_dump($conn->lastInsertId());
      $conn->exec('DROP TABLE testIncrement');
      

      当我运行这个脚本时,输出是

      string(1) "1"
      

      【讨论】:

      • 是的,它包含在内,但为 NULL,因此 MySQL 正在分配 ID 值。在我的所有数据库表中,主键 /auto_increment 的列名都称为“id”。我刚刚检查了 SQL 查询加倍,并且正确的 INSERT 是在调用 lastInsertID() 方法之前运行的最后一个查询。
      • 我忘了提到NULL 值不包含在我的框架的查询中。就在我使用var_dump() 函数时,我可以看到相关表的所有列(如果没有分配值,则显示该列的值为NULL
      • 我添加了示例代码来测试这是 PDO 问题还是您的应用程序/框架的问题。
      • 感谢您的帮助。我做了类似的代码示例来测试 PDO,仍然得到0。我将尝试重新安装 XAMPP。但是在我的服务器上,我的框架和代码示例(我的和你的)运行良好,
      • 重新安装 XAMPP 就可以了。非常感谢您抽出宝贵时间帮助 Gary G。
      猜你喜欢
      • 2022-12-19
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      相关资源
      最近更新 更多