In this quick tip i'll show you a method that i use for database querying. It simplifies the way you process and pass variables into the query.
This is a neat method i'm using in the Isis framework that is running this webpage and a few others. Normally if you want to have your query prepared for the database, you have to consider one thing: SQL injection. If you don't know what that is, there's lots of material on the internet about it, just google for "sql injection" and you'll find out. And if you don't wanna google, just trust me: it's a bad thing that you don't want to leave unchecked. But this tip isn't about injections: it's about the way you deal with them. There are a couple of ways to deal with an SQL injection, but they use a bit of work and for lazy people like me it's unacceptable :) Let's consider the following example:
$user = mysql_real_escape_string($user);
$name = mysql_real_escape_string($name);
$q = "SELECT * FROM table WHERE user='{$user}' "
. "AND name='{$name}' LIMIT 5";
$res = mysql_query($q);
This is one of the ways to do it. The thing that bugs me in this example is that you have to process the variables before adding them to the query. So what if we have like 4 or 5 variables? How about 10? You'd have to
mysql_real_escape_string() them all if they all come from user input. So i've decided to simplify things here and started looking for a way to make this process easier. I thought of several ways, but ended up using one in particular. Actually, the Isis framework is using a little bit different version, because it has database interfaces and objective classes so the example i'm going to give you won't be exactly the same. It will be a function instead. And here it is:
function mquery()
{
$args = func_get_args();
if (count($args) < 1)
return false;
if (count($args) < 2)
return mysql_query($args[0]);
else
{
$query = $args[0];
array_shift($args);
foreach ($args as &$val)
$val = mysql_real_escape_string($val);
$query = vsprintf($query, $args);
return mysql_query($query);
}
}
Now how does this stuff work? Do you know a neat function, called
sprintf()? Here's an example:
$number = 'five';
$text = sprintf('the number is %s', $number);
Well, that's exactly how this query function works. If you pass only one argument to it - the function will assume there are no parameters in the query and pass the entire thing. If you, however, pass an additional argument, the function will insert this argument in an appropriate space in the query string. Let's see an example to better demonstrate the functionality. Here's the same example i used in the beginning of this tip:
$q = "SELECT * FROM table WHERE user='%s' "
. "AND name='%s' LIMIT 5";
$res = mquery($q, $user, $name);
Now isn't that shorter than before? So everywhere you want to add a string from user input, you add the
%s instead and in the query function pass the variable. The
mquery() function will do the
mysql_real_escape_string() on all the arguments (except the first) you pass to it and replace the
%s with the appropriate argument. So basically the
mquery() works like
sprintf(), except it escapes every parameter and queries the final result. If you want an integer instead of a string, use
%d instead of
%s, but note that
mquery() will still initially treat it as a string and if it's not a real integer, it will be converted to 0 by PHP. So in the integer or float case you should check if it is really and integer or float and inform your user if it isn't instead of blindly converting it to string and querying with it.