PHP/MySQL insert row then get 'id'
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
After inserting a row into a MySQL table with an AUTO_INCREMENT primary key, you need to retrieve the generated ID. PHP provides mysqli_insert_id() (procedural) or $mysqli->insert_id (object-oriented) for MySQLi, and $pdo->lastInsertId() for PDO. These return the ID from the last INSERT on the current connection, making them safe for concurrent applications.
Using MySQLi (Object-Oriented)
Using MySQLi (Procedural)
Using PDO (Recommended)
PDO provides a database-agnostic interface with better error handling:
Inserting Multiple Rows and Getting IDs
When inserting multiple rows, insert_id returns the ID of the first row in a multi-row insert:
For guaranteed individual IDs, insert one row at a time:
INSERT with RETURNING (MySQL 8.0.21+ / MariaDB)
MySQL does not support RETURNING natively, but you can use LAST_INSERT_ID() in a follow-up query:
PostgreSQL supports RETURNING directly:
Thread Safety and Concurrency
insert_id / lastInsertId() is per-connection, not per-table. This means:
This is safe for concurrent web applications where each request has its own database connection.
Using Transactions
Common Pitfalls
- Using the wrong connection:
insert_idreturns the last ID for that specific connection object. If you have multiple connections, call it on the same connection that performed the insert. - No AUTO_INCREMENT column: If the table does not have an
AUTO_INCREMENTcolumn,lastInsertId()returns 0. Make sure the table hasid INT AUTO_INCREMENT PRIMARY KEY. - INSERT ... ON DUPLICATE KEY UPDATE: If the row already exists and is updated (not inserted),
lastInsertId()returns the existing row's ID only ifLAST_INSERT_ID(id)is used in theON DUPLICATE KEY UPDATEclause. - String return type:
$pdo->lastInsertId()returns a string, not an integer. Cast to int if needed:(int) $pdo->lastInsertId(). - SQL injection: Never concatenate user input into SQL strings. Always use prepared statements with parameterized queries.
$pdo->query("INSERT INTO users VALUES ('$name')")is vulnerable.
Summary
- Use
$mysqli->insert_id(MySQLi) or $pdo->lastInsertId()(PDO) to get the auto-generated ID after an INSERT - The ID is per-connection, making it safe for concurrent applications
- Always use prepared statements to prevent SQL injection
- For multi-row inserts,
lastInsertId()returns the first row's ID — insert individually to get each ID - Use PDO over MySQLi for database-agnostic code and better error handling
Related reading
- picking a shardkey for mongodb
- pip install mysql-python fails with EnvironmentError mysql_config not found
- pip install mysql-python fails with EnvironmentError mysql_config not found
- Pivot or equivalent in clickhouse
- PlayFramework with Morphia?
- Please explain about insertablefalse and updatablefalse in reference to the JPA Column annotation
- Please use 'MongoMappingContextsetAutoIndexCreationboolean' or override 'MongoConfigurationSupportautoIndexCreation' to be explicit
- Populate a database with TestContainers in a SpringBoot integration test

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.