Did you know that PHP has some pretty powerful type casting functionality built-in? It’s no surprise if you comprehend the roots of PHP (since it’s written in C), but I can’t help but think that casting is an often-missed tool when a PHP developer is trying to ensure data integrity.
Just for a moment, let me define type casting in case you weren’t “in the know”:
According to Wikipedia, “in computer science, type conversion or typecasting refers to changing an entity of one data type into another. “
So, in laymen terms, casting is an easy way to turn one type of data into another type. For example: converting a “string” variable filled with essentially text into an integer variable containing the same numbers but now representing a value. This makes it easy to do math with the value of what once was just a random string of characters.
The following cast types are allow in PHP:
- String – (string)
- Boolean – (bool), (boolean)
- Integer – (int), (integer)
- Binary – (binary) [PHP 6]
- Floating Point – (float), (double), (real)
- Array – (array)
- Object – (object)
So, in the real world, when does casting actually come in handy?
Normally, PHP handles all this stuff automatically behind the scenes. But, as is normal, dealing with MySQL database interaction is something to always take seriously — and type casting can help you out!
We’re going to assume your aren’t using the PDO Prepare statement (though you should be). As a PHP developer, a major part of your job is containing the inherent security risks of user input. It’s especially important when these inputs interact directly with the database.
So, your simplified (e.g. – don’t complain) database interaction code might look something like this:
$id = mysql_real_escape_string($_POST['input']);
$SQL = 'SELECT * FROM table WHERE id = ' . $id;
Call me an overly nervous Ned, but I’d prefer to use the following code:
$id = mysql_real_escape_string($_POST['input']);
$SQL = 'SELECT * FROM table WHERE id = ' . (int)$id;
Did you notice the subtle change? See the ‘int’ cast of the $id in the SQL statement?
This should certainly help to ensure that I haven’t missed any security holes for this query. Some might say it’s overkill, but I just wanted a simple explanation for using casting, so get off your almighty soapbox already.
Anyways, as you can see, type casting in PHP has real-world uses. Delve into type casting a little more and you’ll find a huge number of cases where it can make your code that much more bullet-proof.
So seriously, try out PHP Type Casting.
September 28th, 2007 at 7:51 am
Great post, Ned! That is your name from now on.
September 28th, 2007 at 10:03 pm
I use sprintf for the same purpose, with the plus side being that you can keep all your queries in a config file.
September 28th, 2007 at 10:04 pm
Bah, bad formatting.
sprintf(‘SELECT * FROM table WHERE id = %d’, mysql_real_escape_string($_POST['input']));
June 27th, 2008 at 11:47 am
Wouldn’t it be just as secure to use the following:
$id = number_format($_POST['id'], 0, “”, “”);
$sql = “SELECT * FROM table WHERE id = $id”;
This way, if the posted value is not a integer, 0 is returned at the query doesn’t fail?
August 25th, 2008 at 3:12 am
Hi…. I want to convert my array into string using typecasting without using implode. I tried with (string)Array. But it didn’t worked. How is it possible to convert array to string using typecasting?
December 5th, 2008 at 6:33 am
computerzworld
serialize(array) will turn your array into a string.
unserialize(string) will turn it back into an array.
Or >>
$string = “”;
foreach ($array as $key => $value):
$string .= $value . ‘ ‘;
endforeach;
December 8th, 2008 at 12:16 pm
Actually the best way would be:
$SQL = ‘SELECT * FROM table WHERE id = ‘ . (int) $_POST['input'];
you do not need mysql_real_escape_string when you use (int), because integers cannot be used for SQL injections.
to computerzworld:
if implode and (string) don’t do what you want then use foreach
January 28th, 2009 at 2:43 am
I agree with Hans. Why use mysql_real_escape_string if you know that it should be an integer?? Casting (int) will do.
It is not only an overkill but also contributing to the global warming. I mean performing senseless computations. Besides calling a function takes time, while (int) is really fast.
October 6th, 2009 at 4:22 pm
Alex, hans: if you make a query function, and keep your queries as strings, you can automate it, and use %s, without SQL injection.
December 8th, 2009 at 1:04 am
Thats all good, but has anyone ever notice that php pretty much sorts the tyes out for herself.
The following 3 all return the same result (10.24) …
echo ((int)’1024′) / 100;
echo ‘1024′ / 100;
echo ‘1024′ / ‘100′;
So why?
March 24th, 2010 at 5:10 am
Eugene,
The reason why is you have to force the variable to become an integer for security.
Consider a page which uses a GET request:
product.php?id=123
If I’m a nasty hacker, I can potentially do this:
product.php?id=’ or ‘1′ = ‘1
Which could turn (behind the scenes) into
“SELECT * FROM admin_users WHERE username = ‘admin’ and password = ‘xxx’ OR ‘1′ = ‘1′;”
PHP won’t automatically convert my GET variable into an integer. However, if I force it to, by casting, the string: ‘ or ‘1′ = ‘1 will never be passed to my database, but the string 123 will be passed because it can be cast.
Hope that explains it.
April 23rd, 2010 at 8:29 pm
I use typecasting all of the time. I think it can be quite a nice way to slim down your, code in some cases. For instance:
if (!is_array($data)) {
$data = array($data);
}
//foreach over $data
With typecasting I can do this:
$data = (array) $data;
//foreach over $data
I also use it regularly to ensure that the correct type is returned by a method.
Please correct me if you think this is wrong.
June 18th, 2010 at 6:37 am
[...] A short tip, you can use cast type to avoid SQL Injection in WHERE clause where is possible. $sql= 'SELECT * [...]