All posts
PHPSeptember 9, 20269 min read

How to Insert Form Data Into a Database With PHP

Learn how to insert form data into a database with PHP using safe, beginner-friendly code. Step-by-step tutorial with a working example and full explanations.

F
Fepiq Team
Fepiq

Want to know how to insert form data into a database with PHP? In short: you build an HTML form, send its data to a PHP script, connect that script to your database, and use a "prepared statement" to save the data safely. This guide walks through every one of those steps with small, copy-pasteable code examples, so you can build a working "save to database" form even if you have never done it before.

We will use PostgreSQL as the database in this tutorial, because it is free, easy to install, and works the same way on Windows, Mac, and Linux. If you have not connected PHP to a database yet, read our guide on how to connect PHP to a PostgreSQL database first, then come back here.

What you need before you start

  • PHP installed on your computer (version 8 or newer is best).
  • A PostgreSQL database you can connect to (local or online).
  • A code editor, such as VS Code.
  • Basic comfort with HTML forms. If not, read our PHP form handling guide first — this tutorial builds directly on it.

Step 1: Create a table to store the data

Before PHP can save anything, the database needs a table to save it into. Open psql (PostgreSQL's command-line tool) or a database GUI and run this:

sql
CREATE TABLE contacts (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL,
  message TEXT
);

Line by line: CREATE TABLE contacts makes a new table named contacts. id SERIAL PRIMARY KEY creates a column that auto-numbers every row (1, 2, 3...) and uniquely identifies it. name and email are VARCHAR columns, which hold short text up to the number of characters in the brackets. NOT NULL means the form must not leave that field empty. message is a TEXT column, for longer text with no length limit.

Step 2: Build the HTML form

Next, create a file named form.php with a normal HTML form inside it:

php
<form action="save.php" method="POST">
  <label>Name: <input type="text" name="name" required></label><br>
  <label>Email: <input type="email" name="email" required></label><br>
  <label>Message: <textarea name="message"></textarea></label><br>
  <button type="submit">Send</button>
</form>

Line by line: action="save.php" tells the browser which PHP file should receive the data when the form is submitted. method="POST" sends the data in the request body instead of the URL, which is the right choice for saving data (we cover why in our PHP form handling guide). Each input has a name attribute — name="name", name="email", name="message" — and PHP uses these exact names to read the values later. required simply stops the browser from submitting empty fields.

Step 3: Connect to the database with PDO

PDO (PHP Data Objects) is the recommended way to talk to a database in PHP, because it works with many database types and makes safe queries easy. Create a file named db.php:

php
<?php
$host = "localhost";
$db   = "myapp";
$user = "myapp_user";
$pass = "secret-password";

$pdo = new PDO("pgsql:host=$host;dbname=$db", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Line by line: the first four lines are just variables holding your database name, host, username, and password. new PDO(...) opens the connection — the "pgsql:" prefix tells PHP to use the PostgreSQL driver. setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) tells PDO to throw a clear error message if something goes wrong, instead of failing silently.

Not sure how the PHP-to-PostgreSQL connection itself works? Read the full beginner walkthrough before moving on.

Read: Connect PHP to PostgreSQL

Step 4: Insert the form data safely

This is the most important step. Never build a query by joining text together with the values a user typed — that opens the door to SQL injection, where someone types malicious code into your form instead of a name. Instead, use a prepared statement, which keeps the query structure and the user's data completely separate. Create save.php:

php
<?php
require "db.php";

$name    = $_POST["name"];
$email   = $_POST["email"];
$message = $_POST["message"];

$stmt = $pdo->prepare(
  "INSERT INTO contacts (name, email, message) VALUES (:name, :email, :message)"
);

$stmt->execute([
  ":name"    => $name,
  ":email"   => $email,
  ":message" => $message,
]);

echo "Thanks! Your message has been saved.";

Line by line: require "db.php" reuses the connection code from Step 3 so we don't repeat it. The three $_POST lines read the values the user typed, using the exact name attributes from the HTML form. $pdo->prepare(...) tells the database "here is the shape of a query I want to run," using placeholders like :name instead of real values. $stmt->execute([...]) then sends the real values in safely — PDO makes sure they are treated as plain data, never as part of the SQL command itself. Finally, echo prints a confirmation message back to the browser.

Why not just write the query as one string?

You might see older tutorials write something like "INSERT INTO contacts VALUES ('$name', '$email')" directly. This works until someone types a value like ' OR '1'='1 into a field — with a prepared statement, that text is always treated as harmless data. With a hand-built string, it can change what the query does. Prepared statements cost nothing extra to write and remove this risk completely, so use them from day one.

Step 5: Check that it worked

Open form.php in your browser, fill in the fields, and click Send. You should see the "Thanks! Your message has been saved." message. To confirm the row is really in the database, run this in psql:

sql
SELECT * FROM contacts ORDER BY id DESC LIMIT 1;

This selects every column (*) from the contacts table, orders the rows by id from highest to lowest, and LIMIT 1 keeps only the newest one — so you can quickly see the row your form just created.

Common mistakes to avoid

MistakeWhat happensFix
Building SQL with string concatenationOpens your app to SQL injection attacksAlways use prepared statements with placeholders
Trusting $_POST values directlyEmpty or badly formatted data gets savedCheck required fields and validate email format before inserting
Not checking for connection errorsThe page shows a blank screen with no clue whyTurn on PDO::ERRMODE_EXCEPTION as shown in Step 3
Reusing the GET method for saving dataForm data appears in the URL and can be resubmitted by refreshingUse method="POST" for anything that changes data

What to learn next

  • Add server-side validation, such as checking the email field actually looks like an email.
  • Show the saved data back to the user with a SELECT query on a separate page.
  • Learn PHP arrays if you want to loop over and display multiple saved rows at once.

Frequently asked questions

Do I need PDO, or can I use mysqli instead?+

mysqli also works, but it only supports MySQL, while PDO supports PostgreSQL, MySQL, SQLite, and more with almost the same code. PDO's prepared statements are just as safe, so most beginners are better off learning PDO first.

Why does my form say 'Undefined array key' when I submit it?+

This means an input field's name attribute in your HTML does not match the key you are reading from $_POST in PHP. Double-check that name="email" in the form matches $_POST["email"] exactly, including capitalization.

Is it safe to store passwords the same way as this example?+

No. Names and messages can be saved as plain text, but passwords must be hashed first using PHP's password_hash() function before you insert them. Never save a password exactly as the user typed it.

How do I prevent someone from submitting the form twice?+

The simplest fix is to redirect the user to a new page after a successful insert, using PHP's header("Location: thanks.php") function. This stops the browser's refresh button from resubmitting the same POST request.

Can I insert data from multiple form fields at once, like a list of items?+

Yes — give each input the same name with square brackets, like name="items[]", and PHP collects them into an array automatically. You can then loop over that array and run the insert once per item.

Want a developer to build and secure your PHP forms and database for you?

Talk to Fepiq

Get new posts in your inbox

Occasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.

Keep reading

Related posts

All posts

Let's build something

Ready to ship your next product with Fepiq?

Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.