web-dev-qa-db-ja.com

PDO lastInsertId()は常に0を返します

私は問題に遭遇しました。私のフレームワークはPHP 5.3.0で問題なく動作していました。PHPバージョンをPHP 5.4.xとフレームワークの一部で問題が発生し始めました。

PHPバージョンアップグレード後、PDO lastInsterId()は常に_0_を返します。

idという自動インクリメントフィールドがあります。問題なくデータベースにデータを追加しています。

何らかの理由で、最後の挿入IDとして0を取得し続けます。

これが私のコードです。

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クエリで最後のIDを取得する前に、この問題を解決していただければ幸いです(:

16
Revenant

Php/PDOまたはフレームワークのバグ以外に、2つの可能性があります。 lastInsertId()が挿入とは異なるMySQL接続で呼び出されるか、auto_incrementに生成させるのではなく、アプリケーション/フレームワークでIDを生成して挿入します。テーブルのどの列が主キー/ 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"
20
Gary G

もう1つの問題は、$ pdo-> query($ sql)の代わりに$ pdo-> exec($ sql)を使用することです。

$ pdo-> lastInsertId()を使用すると、exec($ sql)は常に0を返します。したがって、代わりにquery()を使用してください。

2
slawkens

例外がスローされない場合、lastInsertIdは0を返します。ただし、commitを呼び出す前にlastInsertIdが呼び出されると、正しいIDが返されます。

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

1
Ivan Fretes

トランザクションをコミットした後、PDO :: lastInsertID()は0を返すため、トランザクションがコミットされる前にこのメソッドを呼び出すのが最善です。

1
Harry Lewis

外部キーの制約が原因で最後の挿入ステートメントが失敗したときに0を取得しました。 last_errorは文字列でした。

0
Peter Ajtai