PHP Conference Japan 2024

mysqli::$insert_id

mysqli_insert_id

(PHP 5, PHP 7, PHP 8)

mysqli::$insert_id -- mysqli_insert_id返回上次查询生成的 AUTO_INCREMENT 列的值

描述

面向对象风格

过程式风格

mysqli_insert_id(mysqli $mysql): int|string

返回在具有 AUTO_INCREMENT 属性的列的表上执行 INSERTUPDATE 查询时生成的 ID。在多行 INSERT 语句的情况下,它返回第一个成功插入的自动生成的值。

使用 LAST_INSERT_ID() MySQL 函数执行 INSERTUPDATE 语句也会修改 mysqli_insert_id() 返回的值。如果使用 LAST_INSERT_ID(expr) 生成 AUTO_INCREMENT 的值,则它返回最后一个 expr 的值,而不是生成的 AUTO_INCREMENT 值。

如果先前的语句没有更改 AUTO_INCREMENT 值,则返回 0mysqli_insert_id() 必须在生成值的语句之后立即调用。

参数

mysql

仅过程式风格:由 mysqli_connect()mysqli_init() 返回的 mysqli 对象

返回值

先前查询更新的 AUTO_INCREMENT 字段的值。如果连接上没有先前的查询,或者查询没有更新 AUTO_INCREMENT 值,则返回零。

仅使用当前连接发出的语句会影响返回值。该值不受使用其他连接或客户端发出的语句影响。

注意:

如果数字大于最大 int 值,则将作为字符串返回。

示例

示例 #1 $mysqli->insert_id 示例

面向对象风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$mysqli->query("CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
$mysqli->query($query);

printf("New record has ID %d.\n", $mysqli->insert_id);

/* drop table */
$mysqli->query("DROP TABLE myCity");

过程式风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

mysqli_query($link, "CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
mysqli_query($link, $query);

printf("New record has ID %d.\n", mysqli_insert_id($link));

/* drop table */
mysqli_query($link, "DROP TABLE myCity");

以上示例将输出

New record has ID 1.
添加注释

用户贡献的注释 9 条注释

will at phpfever dot com
18 年前
我收到了很多关于 insert_id 属性存在 bug 的陈述,因为它“有时有效”。请记住,当使用 OOP 方法时,mysqli 类的实际实例化将保存 insert_id。

以下代码将返回空值。
<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'The ID is: '.$result->insert_id;
}
?>

这是因为 insert_id 属性不属于结果,而是属于实际的 mysqli 类。这将有效

<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'The ID is: '.$mysqli->insert_id;
}
?>
mmulej at gmail dot com
3 年前
目前还没有使用预处理语句的示例。

```php
$u_name = "John Doe";
$u_email = "[email protected]";

$stmt = $connection->prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->bind_param('ss', $u_name, $u_email);
$stmt->execute();

echo $stmt->insert_id;
```

对于 UPDATE 操作,只需相应地更改查询字符串和绑定参数,其余保持不变。

当然,表需要具有 AUTOINCREMENT PRIMARY KEY。
adrian dot nesse dot wiik at gmail dot com
1 年前
如果您尝试使用 ON DUPLICATE KEY UPDATE 插入一行,请注意,如果触发了 ON DUPLICATE KEY UPDATE 子句,则 insert_id 不会更新。

当你仔细想想,这实际上非常合乎逻辑,因为 ON DUPLICATE KEY UPDATE 是一个 UPDATE 语句,而不是 INSERT 语句。

在最坏的情况下,如果您正在迭代某些内容并执行 INSERT 操作,同时在后面的代码中依赖 insert_id,那么在触发 ON DUPLICATE KEY UPDATE 的迭代中,您可能会指向错误的行!
bert at nospam thinc dot nl
16 年前
注意 $db->insert_id 的 oo 风格用法。当 insert_id 超过 2^31 (2147483648) 时,获取插入 ID 会产生错误的、过大的数字。您最好使用过程化的 mysqli_insert_id( $db ) 代替。

[由 danbrown AT php DOT net 编辑:这是 32 位有符号整数限制的另一个典型示例。]
www dot wesley at gmail dot com
5 年前
当使用“INSERT ... ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)”时,AUTO_INCREMENT 将在 InnoDB 表中增加,但在 MyISAM 表中不会增加。
Nick Baicoianu
17 年前
在具有 AUTO_INCREMENT 字段的表上运行扩展插入时,mysqli_insert_id() 的值将等于插入的*第一*行的值,而不是您可能期望的最后一行的值。

<?
//mytable 具有自动增量字段
$db->query("INSERT INTO mytable (field1,field2,field3) VALUES ('val1','val2','val3'),
('val1','val2','val3'),
('val1','val2','val3')");

echo $db->insert_id; //将回显插入的第一行的 ID
?>
jpage at chatterbox dot fyi
1 年前
不清楚并发控制如何影响此函数。当您对 mysql 进行两次连续调用,而第二次调用的结果依赖于第一次调用时,另一个用户可能在此期间进行了插入。

文档对此保持沉默,因此我始终在插入前后确定自动增量的值以防止这种情况发生。
alan at commondream dot net
20 年前
我在获取插入 ID 时遇到了一些问题,并进行了一些测试。最后发现,如果您在获取最后插入的 ID 之前提交事务,它每次都会返回 0,但是如果您在提交事务之前获取最后插入的 ID,则会获得正确的值。
owenzx at gmail dot com
11 年前
示例缺少 multi_query 中的 insert_id。这是我的示例
假设您在 mysql 中有一个新的 test_db,如下所示

create database if not exists test_db;
use test_db;
create table user_info (_id serial, name varchar(100) not null);
create table house_info (_id serial, address varchar(100) not null);

然后运行以下 php 文件

<?php
define
('SERVER', '127.0.01');
define('MYSQL_USER', 'your_user_name');
define('MYSQL_PASSWORD', 'your_password');

$db = new mysqli(SERVER, MYSQL_USER, MYSQL_PASSWORD, "test_db", 3306);
if (
$db->connect_errno)
echo
"create db failed, error is ", $db->connect_error;
else {
$sql = "insert into user_info "
. "(name) values "
. "('owen'), ('john'), ('lily')";
if (!
$result = $db->query($sql))
echo
"insert failed, error: ", $db->error;
else
echo
"last insert id in query is ", $db->insert_id, "\n";
$sql = "insert into user_info"
. "(name) values "
. "('jim');";
$sql .= "insert into house_info "
. "(address) values "
. "('shenyang')";
if (!
$db->multi_query($sql))
echo
"insert failed in multi_query, error: ", $db->error;
else {
echo
"last insert id in first multi_query is ", $db->insert_id, "\n";
if (
$db->more_results() && $db->next_result())
echo
"last insert id in second multi_query is ", $db->insert_id, "\n";
else
echo
"insert failed in multi_query, second query error is ", $db->error;
}
$db->close();
}
?>

您将获得如下输出

last insert id in query is 1
last insert id in first multi_query is 4
last insert id in second multi_query is 1

结论
1 insert_id 在 multi_query 中有效
2 insert_id 是 mysql 在您插入多个值时使用的第一个 ID
To Top