That's quite interesting question but the answer is not that easy.
What is the proper time to use real_escape_string? When data arrives in POST, or just before composing the query?
NEITHER
Let me explain it a bit.
First, let's sort out the terminology. There are many mistakes in the way the question put in.
- Let's talk not of escaping using real_escape_string but rather of formatting. Just because escaping has a very limited use - it's only a part of the formatting rules of just one type of SQL literals. While other types require different formatting rules.
- Therefore, formatting when data "arrives in POST" is out of question - we just can't tell which field is going into which position in the query and thus we just don't know which rules to apply.
- Last but not least: nor POST nor any other external source has absolutely nothing to do with query formatting. Once you have to put a string literal into query, you have to format it according to SQL syntax rules, no matter of it's source. Same goes for the numbers and such.
So, the only proper time when we have to format our data is right before the query composing.
Yet applying real_escape_string() right in the application code is a very bad practice.
- As it was mentioned above, escaping is insufficient to format a string. String formatting involves both escaping and quoting. So, whatever facility intended to format strings for the SQL query, it should always perform both tasks, not one. Both quoting and escaping. Because these 2 rules are totally useless if applied one without another. So, it's essential to couple them together, in one facility.
- Don't forget of different formatting rules for different data types. Numbers have to be cast to it's type explicitly, while escaping will do no good for them.
- Manual escaping is just silly. Repeated
$mysqli->real_escape_string('$test')
makes your code bloated and hard to read. Why not to ask a database driver to do all the formatting for you? So, you have to follow the most modern technology - use a placeholder to represent data in the query. While processing such a placeholder, driver will automatically format the data going on it's place.
And it will be either safe and convenient.
There are 2 methods of using placeholders easy way (without manual binding which is no better than manual escaping in terms of readability):
- Use PDO, as it lets you just pass a variable to be used in the prepared query
so, the code going to be
$db->prepare("SELECT * from test_panel where test=?");
$db->execute(array($_POST['test']));
and PDO will do all the formatting internally
- or invent your own wrapper to implement placeholders
like this one
function paraQuery()
{
global $mysqli;
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = $mysqli->real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = $mysqli->query($query);
if (!$result)
{
throw new Exception($mysqli->error()." [$query]");
}
return $result;
}
$query = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);
or, for your current query:
$result = paraQuery("SELECT * from test_panel where test=%s", $_POST['test']);
look - it become short, sane and safe.