Share PHP Gotcha: Bigint with sprintf()
December 3rd, 2008 by Erik
Today I am working on modification of an FB application to permit installation on “pages” in addition to profiles. Facebook has switched (several months ago) to using 64bit integer values for id’s site wide. In the code I use sprintf to create stored procedure calls and couldn’t figure out why the values the the database weren’t matching up with my expectations… the following code would output 536035818 instead of the much larger 30600806890 value I expected. Clearly this is a 32bit vs 64bit.
$big_int = 30600806890; $format = "%d"; $new_string = sprintf($format, $big_int); print $new_string; |
Since updating to a fully 64 bit platform and so on really isn’t an option, I needed a work around. I composed a quick test for my value and ran it. The test as you can see, it provides output for each of the valid substitution types in sprintf.
$big_int = 30600806890; $type = array("%b","%c","%d","%e","%u","%f","%F","%o","%s","%x","%X"); for($i=0;$i<count($type);$i++){ print $type[$i] . ": " . sprintf($type[$i], $big_int) . "\n"; } |
This results with the list below. Obviously floating point numbers and strings are the only way to handle these bigint values. A simple drop in value is of course to swap %s for %d as needed, but you lose some type catching which may cause security issues. Instead, I recommend using %0.0f which will suppress the decimal portion – keeping the int an int – while keeping the numeric type checking intact.
%b: 11111111100110100000111101010 %c: ? %d: 536035818 %e: 3.06008e+10 %u: 536035818 %f: 30600806890.000000 %F: 30600806890.000000 %o: 3774640752 %s: 30600806890 %x: 1ff341ea %X: 1FF341EA
You should follow me on Twitter.
October 28th, 2009 at 10:33 am
I’ve since learned that this is actually because PHP silently converts integer values to floats behind the scenes for you. See my latest troubles and work around here:
http://af-design.com/blog/2009/10/28/php-64-bit-integer-modulus-almost/
April 27th, 2010 at 1:32 am
[...] had to update my ID columns in my database to use BIGINT so that they could store 20 digits. Other people have been impacted by this because they actually coded Facebook applications. Share and [...]