【PDO拡張】lastInsertId関数が0を返す理由
問題
PHP の PDO 拡張機能を使用してデータを挿入する場合、最後に挿入されたレコードの ID を戻り情報として取得する必要がある場合があります。どうすればこの要件を達成できるでしょうか?
lastInsertId 関数
PDO の lastInsertId 関数を使用します。
しかし、最近使用中に、lastInsertId 関数が 0 を返す場合があることがわかりました。なぜこのようなことが起こっているのでしょうか?
まず、PHP マニュアルの lastInsertId 関数の説明を見てみましょう。
最後に挿入された行の ID またはシーケンス値を返します。
次の例を見てみましょう。
テスト例
自動インクリメント制約を使用した主キーは ID フィールドです。
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'root'; try{ $dbh = new PDO($dsn, $user, $password); }catch(PDOException $e){ echo "Connection failed: " . $e->getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)'; $data = array( ':id' => '', ':name' => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)'; $new_data = array( ':id' => '', ':name' => 'user_new' ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo 'last id: ' . $last_id;
結果
last id: 11
主キーは ID フィールドであり、auto は使用されません-インクリメント制約。
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'root'; try{ $dbh = new PDO($dsn, $user, $password); }catch(PDOException $e){ echo "Connection failed: " . $e->getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)'; $data = array( ':id' => $i, ':name' => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)'; $new_data = array( ':id' => '', ':name' => 'user_new' ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo 'last id: ' . $last_id;
結果
last id: 0
主キーは ID フィールドではなく、主キーkey は自動インクリメント制約を使用します。
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'root'; try{ $dbh = new PDO($dsn, $user, $password); }catch(PDOException $e){ echo "Connection failed: " . $e->getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)'; $data = array( ':tbl_id' => $i, ':name' => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)'; $new_data = array( ':tbl_id' => '', ':name' => 'user_new' ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo 'last id: ' . $last_id;
結果
last id: 11
主キーは ID フィールドではないため、使用されません自動インクリメント制約。
<?php $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'root'; try{ $dbh = new PDO($dsn, $user, $password); }catch(PDOException $e){ echo "Connection failed: " . $e->getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)'; $data = array( ':tbl_id' => uniqid(), ':name' => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)'; $new_data = array( ':tbl_id' => uniqid(), ':name' => 'user_new' ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo 'last id: ' . $last_id;
結果
last id: 0
PHP ソースコードを表示
を参照してください。一部の例では 0 が返され、一部の例では最新の ID が返されます。それでは、どのような状況で lastInsertId は 0 を返すのでしょうか?インターネットで多くの情報を検索しましたが、必要な答えが見つかりませんでした。PHP ソース コードを開いたところ、関数 last_insert_id の実装ソース コードが次のとおりであることがわかりました。 > ご覧のとおり、関数によって返される ID 値は、mysql API の mysql_insert_id 関数を呼び出して返される値です。
mysql マニュアルを表示
mysql マニュアルを開いて次の段落を見つけてください:
mysql_insert_id() は、値が AUTO_INCREMENT カラムに格納されているかどうかに関係なく、AUTO_INCREMENT カラムに格納された値を返します。 NULL または 0 を格納することによって自動的に生成されるか、明示的な値として指定された LAST_INSERT_ID() は、NULL または 0 以外の明示的な値を格納する場合、LAST_INSERT_ID() によって返される値には影響しません。 🎜>
結論
マニュアルの説明から、テーブル内のフィールドが AUTO_INCREMENT 制約を使用していない場合、mysql_insert_id 関数はフィールドに格納されている値を返すことがわかります。 AUTO_INCREMENT 制約を使用するか、独自に生成された一意の値を使用する場合、関数は保存した値を返さず、代わりに NULL または 0 を返します。したがって、AUTO_INCREMENT 制約を使用しないテーブル、または ID が自己生成された一意の ID であるテーブルでは、lastInsertId 関数は 0 を返します。
この記事では問題の理由について説明していますが、私の個人的なレベルに限界があるため、ご提案やご批判がございましたら、お気軽にご指摘ください。注: この記事では PHP5.4.15、MySQL5.5.41 を使用しています。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。
