问题
在使用PHP的PDO扩展插入数据的时候,有时候需要获取到最后插入记录的ID作为返回信息。要怎么才能实现这个需求呢?
lastInsertId函数
使用PDO的lastInsertId函数。
但是,最近在使用的过程中发现有时候lastInsertId函数返回的是0。为什么会这样呢?
先来看看lastInsertId函数在 PHP手册 上的说明。
返回最后插入行的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字段,不使用自增约束。
<?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字段,主键使用自增约束。
<?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() returns the value stored into an AUTO_INCREMENT column, whether that value is automatically generated by storing NULL or 0 or was specified as an explicit value. LAST_INSERT_ID() returns only automatically generated AUTO_INCREMENT values. If you store an explicit value other than NULL or 0, it does not affect the value returned by LAST_INSERT_ID().
结论
从手册的描述可以知道, mysql_insert_id 函数返回的是储存在有 AUTO_INCREMENT 约束的字段的值,如果表中的字段不使用 AUTO_INCREMENT 约束或者使用自己生成的唯一值插入,那么该函数不会返回你所存储的值,而是返回NULL或0。因此,在没有使用AUTO_INCREMENT约束的表中,或者ID是自己生成的唯一ID,lastInsertId函数返回的都是0。
本文是探讨一个问题出现的原因,由于个人水平有限,如有建议和批评,欢迎指出。
注:本文使用的是PHP5.4.15,MySQL5.5.41。

PHP kekal sebagai alat yang kuat dan digunakan secara meluas dalam pengaturcaraan moden, terutamanya dalam bidang pembangunan web. 1) PHP mudah digunakan dan diintegrasikan dengan lancar dengan pangkalan data, dan merupakan pilihan pertama bagi banyak pemaju. 2) Ia menyokong penjanaan kandungan dinamik dan pengaturcaraan berorientasikan objek, sesuai untuk membuat dan mengekalkan laman web dengan cepat. 3) Prestasi PHP dapat ditingkatkan dengan caching dan mengoptimumkan pertanyaan pangkalan data, dan komuniti yang luas dan ekosistem yang kaya menjadikannya masih penting dalam timbunan teknologi hari ini.

Dalam PHP, rujukan lemah dilaksanakan melalui kelas lemah dan tidak akan menghalang pemungut sampah daripada menebus objek. Rujukan lemah sesuai untuk senario seperti sistem caching dan pendengar acara. Harus diingat bahawa ia tidak dapat menjamin kelangsungan hidup objek dan pengumpulan sampah mungkin ditangguhkan.

Kaedah \ _ \ _ membolehkan objek dipanggil seperti fungsi. 1. Tentukan kaedah \ _ \ _ supaya objek boleh dipanggil. 2. Apabila menggunakan sintaks $ OBJ (...), PHP akan melaksanakan kaedah \ _ \ _ invoke. 3. Sesuai untuk senario seperti pembalakan dan kalkulator, meningkatkan fleksibiliti kod dan kebolehbacaan.

Serat diperkenalkan dalam Php8.1, meningkatkan keupayaan pemprosesan serentak. 1) Serat adalah model konkurensi ringan yang serupa dengan coroutine. 2) Mereka membenarkan pemaju mengawal aliran pelaksanaan tugas secara manual dan sesuai untuk mengendalikan tugas I/O-intensif. 3) Menggunakan serat boleh menulis kod yang lebih cekap dan responsif.

Komuniti PHP menyediakan sumber dan sokongan yang kaya untuk membantu pemaju berkembang. 1) Sumber termasuk dokumentasi rasmi, tutorial, blog dan projek sumber terbuka seperti Laravel dan Symfony. 2) Sokongan boleh didapati melalui saluran StackOverflow, Reddit dan Slack. 3) Trend pembangunan boleh dipelajari dengan mengikuti RFC. 4) Integrasi ke dalam masyarakat dapat dicapai melalui penyertaan aktif, sumbangan kepada kod dan perkongsian pembelajaran.

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP tidak mati, tetapi sentiasa menyesuaikan diri dan berkembang. 1) PHP telah menjalani beberapa lelaran versi sejak tahun 1994 untuk menyesuaikan diri dengan trend teknologi baru. 2) Ia kini digunakan secara meluas dalam e-dagang, sistem pengurusan kandungan dan bidang lain. 3) Php8 memperkenalkan pengkompil JIT dan fungsi lain untuk meningkatkan prestasi dan pemodenan. 4) Gunakan OPCACHE dan ikut piawaian PSR-12 untuk mengoptimumkan prestasi dan kualiti kod.

Masa depan PHP akan dicapai dengan menyesuaikan diri dengan trend teknologi baru dan memperkenalkan ciri -ciri inovatif: 1) menyesuaikan diri dengan pengkomputeran awan, kontena dan seni bina microservice, menyokong Docker dan Kubernetes; 2) memperkenalkan pengkompil JIT dan jenis penghitungan untuk meningkatkan prestasi dan kecekapan pemprosesan data; 3) Berterusan mengoptimumkan prestasi dan mempromosikan amalan terbaik.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Dreamweaver CS6
Alat pembangunan web visual

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

PhpStorm versi Mac
Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 Linux versi baharu
SublimeText3 Linux versi terkini