An SQL statement is code. When you build an SQL query with concatenation (or something else) you are doing code generation. And this code generation has the same problems when you generating php code (eval ("echo '$variable';");
) or HTML code (<h1><?= $header?></h1>
). There is no "data" in generated code, only code itself.
There are several ways to attempt to avoid unwanted behaviour.
Packing/unpacking: use base64_encode/FROM_BASE64 for data variable for database, use base64_encode/base64_decode for eval, and htmlentities for html.
Escaping: $PDO::quote() for data variable for database, some function for eval (for example return '\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $var) . '\'';
)
(bad) Removing 'dangerous' construction:(for example `$v = preg_replace('/UNION(?:\s+ALL)?\s+SELECT/i', '--', $a);) for database, strip_tags for HTML.
Separate data from code: prepared statements for database, generate function and pass data to it for eval, using Document Object Model for building HTML.
So, the main idea of prepared statements is in separation data from a code. Therefore you must specify directly where the data is and where the code is.
The simplest way to insert with prepared statement is
$pdo->prepare('INSERT INTO `table` (`text`) VALUES(?);')->execute(array($text));
Remember, that prepared statements is prefered way to avoid troubles. If you could use prepared statements -- use it.