Since PHP lacks a decimal type, it only has floats and integers. Arbitrary precision floating points are reasonable once you stop expecting them to be precise. I’ve learned to deal with PHP’s floats, and arbitrary precision floats in general. However, floats behaving totally different based on the current locale, was something I didn’t expect. PHP has this horribly wonderful feature, where using
setlocale() can butcher floats, and make other wise sane SQL and casting expressions an effort in futility. Take the following
- $pi = 3.141593;
- echo (float)(string)$pi; //should output '3.141593'
Now if by accident you have you’ve used
setlocale() to modify your locale to ‘pl_PL’ because you’re making a site in polish. The exact same code now behaves totally different. Instead of the useful pi you are used to you get
3. Thats right, no decimals for you. Its very odd and unexpected that float/string casts are not bi-directional. Even worse is if you try and do some SQL with what you think is a float.
You’ll end up with a nice fat error like
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘(pi) VALUES (3,141593)
Having done a float cast, I expected that the value would be safe to insert. Getting a SQL error back, makes using
setlocale() extremely dangerous if you intend on doing anything with floats. Having floats magically mutate into SQL destroying values is really annoying and dangerous. It also creates difficult to debug issues that are caused by magical global runtime properties being changed. I’m sure there was a good reason for this implementation, but I really question its usefulness, when perfectly safe code transforms into SQL destroying, logic defying craziness because of a simple function call.