Hi internals, I'd like to make two improvements to the printf() functionality exposed by PHP (also affecting other variations like sprintf, vprintf, etc.) These improvements are motivated by https://wiki.php.net/rfc/locale_independent_float_to_string, which will make float to string casts locale insensitive, but not change the behavior of printf() specifiers.
The proposed improvements are: 1. Support for the %h and %H specifiers, which behave the same as %g and %G, but are locale insensitive. These specifiers are already supported internally in PHP (though %h goes by the name of %k for reasons that are not relevant to userland) and is used for formatting floating-point numbers where case-sensitivity is not desired, such as for var_export(). 2. Support for * width and precision, in which case the width/precision is provided as an argument to printf(). This is a feature of printf() in C. The combination of these two features allows us to easily print floating point numbers exactly as PHP would print them: // Locale-sensitive using precision ini setting. sprintf("%.*G", ini_get('precision'), $float); // Locale-insensitive using serialize_precision ini setting. sprintf("%.*H", ini_get('serialize_precision'), $float); Notably, this also supports precision -1 (the default serialize_precision), which will pick the shortest accurate representation of the float. Without these features, it is actually quite hard to replicate PHP's exact behavior. The best approximation I've found is to print with %G at multiple precisions, pick out the shorted one and replace commas with dots on the assumption that comma is the only locale-specific decimal separator. It would be good to expose what PHP can already do directly. Implementations for the two features are available at https://github.com/php/php-src/pull/5432 and https://github.com/php/php-src/pull/5436. Regards, Nikita