自定义PDO数据库类调用lastInsertId()报错的问题咨询
解决"Call to undefined method PDOStatement::lastInsertId()"错误的方案
咱们先来揪出问题的根源:你之所以收到这个错误,是因为**lastInsertId()是PDO连接实例的方法,而不是PDOStatement对象的方法**。你的DB::run()方法返回的是执行SQL后的PDOStatement对象,所以直接在它身上调用lastInsertId()肯定会报错。
接下来给你两种可行的解决思路,你可以根据自己的需求选择:
方案一:直接通过DB类获取PDO实例调用lastInsertId
这个方法最简单,不用修改DB类,只需要调整你的调用代码就行。既然DB::instance()返回的是PDO实例,那我们直接用它来调用lastInsertId()就好:
修改后的调用代码:
require_once '../classes/pdo.php'; $sql="insert into accounts(account_email,account_password) values(:email,:password)"; $values=array(':email'=>'jay.garrick@email.com',':password'=>'blah'); $res = DB::run($sql,$values); // 这里改成通过DB::instance()获取PDO实例再调用方法 $id = DB::instance()->lastInsertId(); echo $id;
方案二:在DB类中封装lastInsertId的获取逻辑
如果想让代码更优雅,不想每次都写DB::instance(),可以在DB类里封装一个获取最后插入ID的静态方法,同时在run()方法执行插入后记录这个ID:
修改后的DB类代码:
class DB { protected static $instance = null; protected function __construct() {} protected function __clone() {} public $pdo; // 新增:存储最后插入的ID private static $lastInsertId = null; public static function instance() { if(self::$instance == null) { $opt = array( PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ); $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR; self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt); } return self::$instance; } public static function __callStatic($method, $args) { return call_user_func_array(array(self::instance(), $method), $args); } public static function run($sql, $args = NULL) { $pdo = self::instance(); if(!$args) { return $pdo->query($sql); } $stmt = $pdo->prepare($sql); $stmt->execute($args); // 执行后更新最后插入的ID self::$lastInsertId = $pdo->lastInsertId(); return $stmt; } // 新增:静态方法获取最后插入的ID public static function getLastInsertId() { return self::$lastInsertId; } }
对应的调用代码就可以写成:
require_once '../classes/pdo.php'; $sql="insert into accounts(account_email,account_password) values(:email,:password)"; $values=array(':email'=>'jay.garrick@email.com',':password'=>'blah'); $res = DB::run($sql,$values); $id = DB::getLastInsertId(); echo $id;
额外注意点
别忘了确保你的accounts表有自增主键字段(比如id INT AUTO_INCREMENT PRIMARY KEY),否则lastInsertId()会返回0或者空值,这和代码无关,是数据库表结构的问题。
内容的提问来源于stack exchange,提问作者Taquito Sensei
相关产品推荐
相关产品推荐

