Escaping single quote in PHP when inserting into MySQL
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Unescaped single quotes in SQL strings break queries and create SQL injection vulnerabilities. The correct solution is prepared statements (PDO or MySQLi), which separate SQL structure from data entirely. Manual escaping with mysqli_real_escape_string() is a fallback, but it is error-prone and unnecessary when prepared statements are available. Never use addslashes() or string replacement for SQL. They do not handle all edge cases and leave you vulnerable.
The Problem
Fix 1: PDO Prepared Statements (Recommended)
Prepared statements send the SQL template and values separately to MySQL. The database handles quoting and escaping, so the single quote in "O'Brien" is never part of the SQL structure.
Fix 2: MySQLi Prepared Statements
Fix 3: PDO with SELECT
Fallback: mysqli_real_escape_string()
If you cannot use prepared statements (legacy code), escape manually:
This escapes single quotes, double quotes, backslashes, NUL bytes, and other special characters. The connection object is required because escaping depends on the connection's character set.
Why NOT to Use These Approaches
Batch Inserts with Prepared Statements
The prepared statement is parsed once and executed multiple times. This is faster and safer than building individual SQL strings.
PDO Connection Best Practices
Setting EMULATE_PREPARES to false ensures the database driver sends the query template and parameters separately, giving true prepared statement protection.
LIKE Queries with Special Characters
Common Pitfalls
- String interpolation with quotes: Never put user input directly in SQL strings (
"VALUES ('$name')"). Always use prepared statements. No amount of escaping is as safe as parameterized queries. - PDO emulated prepares: By default, PDO emulates prepared statements in PHP. Set
PDO::ATTR_EMULATE_PREPARES => falseto use real server-side prepared statements for proper type handling and security. - Forgetting the charset: Without
charset=utf8mb4in the DSN,mysqli_real_escape_string()may not correctly handle multi-byte characters, leaving SQL injection possible even with escaping. - Using deprecated functions:
mysql_real_escape_string()(without thei) is from the removedmysql_*extension. Usemysqli_real_escape_string()or PDO. - Escaping integers: For integer parameters, use
bind_param("i", $id)or cast with(int)$id. Quoting integers as strings can cause index performance issues.
Summary
- Always use prepared statements (PDO or MySQLi). They separate SQL from data completely
- PDO with named parameters (
:name) is the cleanest approach - Set
EMULATE_PREPARES => falseandcharset=utf8mb4in the PDO connection mysqli_real_escape_string()is a fallback for legacy code only- Never use
addslashes(),str_replace(), or string interpolation for SQL - Prepared statements prevent SQL injection by design, not by escaping
Related reading
- Event Sourcing With an Event Store and an ORM
- Exception authenticating MongoCredential and Uncategorized Mongo Db Exception
- Exception when AddWithValue parameter is NULL
- Exception when creating datasource with PostgreSQL driver in Spring Boot
- Exchanging data between Android SQL-Lite and SQL Sever without using webserive
- Exclude a column using SELECT * [except columnA] FROM tableA?
- Executing an update/delete query in the JQPL query
- Existing tools to find unused tables in cassandra cluster

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.