How to Sanitize User Input in PHP: Top Mistakes and Protections

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

"I just escape quotes": why your code is vulnerable

\n\n

If you've ever Googled "How can I sanitize user input with PHP?", you're not alone. This question on Stack Overflow has gathered hundreds of thousands of views. And it's no surprise: the topic of security is one of the hottest in web development.

\n\n

But here's the paradox: most answers to that question are either outdated or dangerous. Developers still write something like mysql_real_escape_string() (which hasn't existed for 10 years) or simply remove "dangerous" characters. Spoiler: it doesn't work.

\n\n

In this article, we'll break down the top 5 mistakes in sanitizing user input in PHP that turn your site into a sieve, and show you how to fix them once and for all.

\n\n

Mistake #1: Blind faith in "sanitization" as a universal cure-all

\n\n

The biggest mistake is thinking there is one function that will "clean" any data. Here's typical beginner code:

\n\n
<?php\n$name = $_POST['name'];\n$name = strip_tags($name);\n$name = addslashes($name);\n// Is the data safe now? No!\n?>
\n\n

The problem is that different contexts require different processing. Validation (format checking) and sanitization (cleaning) are not the same thing. And there's also output escaping, which happens in a completely different place.

\n\n

What to do: Determine what you are doing with the data at each stage. One thing for the database, another for HTML, and a third for JSON.

\n\n

Mistake #2: Using outdated functions (or using them incorrectly)

\n\n

Let's go through the "dinosaurs" of PHP security:

\n\n
    \n
  • mysql_real_escape_string() — removed in PHP 7.0. Forget it.
  • \n
  • addslashes() — does not protect against all SQL injections, especially with multi-byte encodings.
  • \n
  • strip_tags() — removes tags but does not escape output. XSS is still possible via attributes.
  • \n
\n\n

Example of dangerous code that is still found:

\n\n
<?php\n$id = $_GET['id'];\n$id = addslashes($id);\n$query = "SELECT * FROM users WHERE id = '$id'";\n// If id = 1 OR 1=1 -- you've been hacked\n?>
\n\n

What to do: Use prepared statements. This is the only reliable way to protect against SQL injections.

\n\n
<?php\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");\n$stmt->execute(['id' => $_GET['id']]);\n?>
\n\n

See? No sanitization for SQL. Just parameters. The database itself will figure out what is data and what is a command.

\n\n

Mistake #3: Confusing validation and sanitization

\n\n

Many think: "I'll remove all suspicious characters, and it will be safe." But this breaks the application logic. Imagine a user entered the password P@ssw0rd!, and you removed the @ and ! characters. The password becomes Pssw0rd — and the user can no longer log in.

\n\n

Validation — checks if the input matches the expected format (email, number, URL). If not — reject it.

\n\n

Sanitization — removes or modifies unwanted characters, but only when it's really necessary (e.g., for a filename).

\n\n

Example of correct email validation:

\n\n
<?php\n$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);\nif ($email === false) {\n    // Email is invalid — do not save, do not output\n    echo "Enter a valid email";\n    exit;\n}\n// Now $email is a safe string for any purpose\n?>
\n\n

Golden rule: If you expect a number — check that it's a number. If an email — check the format. Everything else — reject it.

\n\n

Mistake #4: Ignoring the output context (XSS)

\n\n

You saved the data to the database using prepared statements. Hooray, no SQL injections. But

Blogs

Book Recommendations