How to Update and Delete Data in MySQL With PHP
Learn how to update and delete data in a MySQL database using PHP and PDO, with safe, copy-paste prepared statement examples explained line by line.
Learn how to update and delete data in a MySQL database using PHP and PDO, with safe, copy-paste prepared statement examples explained line by line.
Want to know how to update and delete data in MySQL with PHP? The short answer: you write an SQL UPDATE or DELETE statement, run it safely from PHP using a prepared statement, and always include a WHERE clause so you only change the row you mean to. In this guide you will build both from scratch, one small step at a time, with no prior database experience needed.
This is the natural next step after learning how to insert data into a database with PHP. Together, insert, read, update, and delete make up what developers call CRUD (Create, Read, Update, Delete) — the four basic operations almost every website needs.
For the examples below, imagine a table called contacts that stores names and email addresses. You can create it with this SQL:
CREATE TABLE contacts (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL
);
INSERT INTO contacts (name, email) VALUES
('Amy Chen', 'amy@example.com'),
('Ben Osei', 'ben@example.com');Line by line: CREATE TABLE contacts makes a new table with three columns. id is a number that MySQL fills in automatically for every new row (AUTO_INCREMENT) and uniquely identifies each row (PRIMARY KEY). name and email store text (VARCHAR means "variable-length text", with a maximum length in parentheses). The INSERT statement adds two starting rows so we have something to update and delete.
PDO (PHP Data Objects) is a built-in PHP tool for talking to databases. We will use it because it works the same way whether your database is MySQL or PostgreSQL, and it makes it easy to write safe queries.
<?php
$host = '127.0.0.1';
$db = 'my_app';
$user = 'root';
$pass = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('Connection failed: ' . $e->getMessage());
}$host, $db, $user, and $pass hold your database connection details. new PDO(...) opens the connection; the first argument is a DSN (data source name) that tells PHP which database driver and database name to use. setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) tells PDO to throw a catchable error instead of failing silently, which makes bugs much easier to find. The try/catch block stops the script safely and shows a message if the connection fails.
The UPDATE statement changes values in existing rows. Its basic shape looks like this:
UPDATE table_name
SET column1 = value1, column2 = value2
WHERE condition;UPDATE table_name picks the table to change. SET lists the columns you want to update and their new values, separated by commas. WHERE condition limits the change to specific rows. If you leave out WHERE, MySQL updates every single row in the table — almost never what you want.
Here is how to run that safely from PHP using a prepared statement, which protects you from SQL injection (a common attack where malicious text is treated as SQL code):
<?php
$newEmail = 'amy.chen@example.com';
$contactId = 1;
$stmt = $pdo->prepare('UPDATE contacts SET email = :email WHERE id = :id');
$stmt->execute([
':email' => $newEmail,
':id' => $contactId,
]);
echo $stmt->rowCount() . ' row(s) updated.';$pdo->prepare(...) writes the SQL once, using named placeholders (:email and :id) instead of putting the real values directly into the string. $stmt->execute([...]) then sends the actual values separately; PDO makes sure they are treated as plain data, never as SQL commands, which is what stops SQL injection. $stmt->rowCount() tells you how many rows were actually changed, which is useful for confirming the update worked.
DELETE removes whole rows from a table. Its basic shape is even simpler than UPDATE:
DELETE FROM table_name
WHERE condition;DELETE FROM table_name says which table to remove rows from. WHERE condition says which rows qualify. Just like with UPDATE, skipping WHERE deletes every row in the table — there is no "undo" button in plain SQL, so double-check your WHERE clause before running it.
<?php
$contactId = 2;
$stmt = $pdo->prepare('DELETE FROM contacts WHERE id = :id');
$stmt->execute([':id' => $contactId]);
echo $stmt->rowCount() . ' row(s) deleted.';This works the same way as the update example: prepare() writes the query with a placeholder, execute() sends the real id value, and rowCount() confirms how many rows were removed. Using the id column (the primary key) in WHERE guarantees you delete exactly one specific row, never more.
In a real website, the new value and the row id usually come from an HTML form, not from a value typed directly into the PHP file. Here is a minimal example that updates a contact's email address:
<form method="post" action="update.php">
<input type="hidden" name="id" value="1">
<label>New email:
<input type="email" name="email" required>
</label>
<button type="submit">Save</button>
</form>The hidden input carries the row's id along with the form without showing it to the user. The email input collects the new value; required means the browser will not submit an empty field. When the user clicks Save, the browser sends both fields to update.php using an HTTP POST request.
<?php
// update.php
$id = $_POST['id'];
$email = $_POST['email'];
$stmt = $pdo->prepare('UPDATE contacts SET email = :email WHERE id = :id');
$stmt->execute([':email' => $email, ':id' => $id]);
header('Location: contacts.php');
exit;$_POST['id'] and $_POST['email'] read the two values the form sent. The prepare/execute pair updates the row safely, exactly like the earlier example. header('Location: contacts.php') redirects the browser back to the contact list once the update is done, and exit stops the script so no extra output is sent after the redirect.
| Operation | SQL keyword | Risk if WHERE is missing |
|---|---|---|
| Read | SELECT | Returns too many rows (annoying, not dangerous) |
| Update | UPDATE | Overwrites every row in the table |
| Delete | DELETE | Permanently removes every row in the table |
“Before running an UPDATE or DELETE on a real database, run the same WHERE clause as a SELECT first. If the SELECT returns exactly the rows you expect, the UPDATE or DELETE is safe to run.”
CRUD stands for Create, Read, Update, and Delete — the four basic actions almost every database-driven website performs on its data. In PHP, Create usually means an INSERT statement, Read means SELECT, and Update and Delete are the two operations covered in this guide.
Both work, but PDO is a good default for beginners because it supports prepared statements, works with several database types (including MySQL and PostgreSQL) using the same syntax, and has a simpler error-handling model. Once you know PDO, learning mysqli later is easy.
Without WHERE, MySQL applies the UPDATE or DELETE to every row in the table, not just the one you meant to change. This is one of the most common and most damaging mistakes beginners make, so it is worth double-checking every time before you run either statement.
Use prepared statements with placeholders, like the :email and :id examples in this guide, instead of inserting variables directly into your SQL string. PDO then sends the values separately from the query, so user input can never be interpreted as SQL commands.
Not by default. Once a DELETE runs, the rows are gone unless you have a recent database backup or are working inside a transaction you have not yet committed. Because of this, many real applications use a 'soft delete' instead, which just marks a row as deleted with a flag rather than removing it.
New to putting data into a database with PHP? Start with our beginner-friendly walkthrough on inserting form data.
Read the PHP insert tutorialYou now know how to update and delete rows in MySQL from PHP, safely and with confidence: write the UPDATE or DELETE statement, always add a WHERE clause, and run it through a prepared statement so user input can never be mistaken for SQL code. Combined with SELECT and INSERT, you have covered all four CRUD operations that power most real-world websites.
Building something bigger than a demo and want a second pair of eyes on your PHP and database setup?
Talk to the Fepiq teamOccasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.
Keep reading
Learn SQL CASE WHEN step by step. This beginner guide shows how to label, group and sort data with simple examples you can copy and run today.
PostgreSQL ILIKE explained for beginners: search text without worrying about case, learn % and _ wildcards, and copy simple examples you can run today.
Let's build something
Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.