mysqli::$insert_id
mysqli_insert_id
(PHP 5, PHP 7, PHP 8)
mysqli::$insert_id -- mysqli_insert_id — 直近のクエリの AUTO_INCREMENT カラムで生成した値を返す
説明
オブジェクト指向型
手続き型
AUTO_INCREMENT
属性を持つカラムがあるテーブル上での
INSERT
や UPDATE
クエリが生成したIDを返します。
INSERT
文が複数の行を変更する場合、
最初に自動生成された値を返します。
MySQL 関数 LAST_INSERT_ID()
を使って
INSERT
や UPDATE
を実行すると、
mysqli_insert_id() が返す値も変更されます。
AUTO_INCREMENT
の値を生成するために
LAST_INSERT_ID(expr)
を使った場合、
生成された AUTO_INCREMENT
の値ではなく、
最後の expr
の値を返します。
直前のクエリが
AUTO_INCREMENT
の値を変更しなかった場合は、
0
を返します。
クエリが値を生成した直後に、
mysqli_insert_id() をコールする必要があります。
戻り値
直前のクエリで更新された 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.
User Contributed Notes 8 notes
I have received many statements that the insert_id property has a bug because it "works sometimes". Keep in mind that when using the OOP approach, the actual instantiation of the mysqli class will hold the insert_id.
The following code will return nothing.
<?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;
}
?>
This is because the insert_id property doesn't belong to the result, but rather the actual mysqli class. This would work:
<?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;
}
?>
There has been no examples with prepared statements yet.
```php
$u_name = "John Doe";
$u_email = "johndoe@example.com";
$stmt = $connection->prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->bind_param('ss', $u_name, $u_email);
$stmt->execute();
echo $stmt->insert_id;
```
For UPDATE you simply change query string and binding parameters accordingly, the rest stays the same.
Of course the table needs to have AUTOINCREMENT PRIMARY KEY.
If you try to INSERT a row using ON DUPLICATE KEY UPDATE, be aware that insert_id will not update if the ON DUPLICATE KEY UPDATE clause was triggered.
When you think about it, it's actually very logical since ON DUPLICATE KEY UPDATE is an UPDATE statement, and not an INSERT.
In a worst case scenario, if you're iterating over something and doing INSERTs while relying on insert_id in later code, you could be pointing at the wrong row on iterations where ON DUPLICATE KEY UPDATE is triggered!
Watch out for the oo-style use of $db->insert_id. When the insert_id exceeds 2^31 (2147483648) fetching the insert id renders a wrong, too large number. You better use the procedural mysqli_insert_id( $db ) instead.
[EDIT by danbrown AT php DOT net: This is another prime example of the limits of 32-bit signed integers.]
When using "INSERT ... ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)", the AUTO_INCREMENT will increase in an InnoDB table, but not in a MyISAM table.
When running extended inserts on a table with an AUTO_INCREMENT field, the value of mysqli_insert_id() will equal the value of the *first* row inserted, not the last, as you might expect.
<?
//mytable has an auto_increment field
$db->query("INSERT INTO mytable (field1,field2,field3) VALUES ('val1','val2','val3'),
('val1','val2','val3'),
('val1','val2','val3')");
echo $db->insert_id; //will echo the id of the FIRST row inserted
?>
What is unclear is how concurrency control affects this function. When you make two successive calls to mysql where the result of the second depends on the first, another user may have done an insert in the meantime.
The documentation is silent on this, so I always determine the value of an auto increment before and after an insert to guard against this.
I was having problems with getting the inserted id, and did a bit of testing. It ended up that if you commit a transaction before getting the last inserted id, it returns 0 every time, but if you get the last inserted id before committing the transaction, you get the correct value.