PHP: setlocale und float Problem

2013-12-10 00:00:00 IN1 , 2023-04-10 14:16:28 IN1


Problembeschreibung

Zu Floats gibt es eine interne und eine externe Repräsentation. Intern arbeitet PHP immer mit . Decimal. Extern kann ein Float Wert jedoch auch mit Komma angegeben sein. Bsp.: var_dump(79.95); würde in letzterem Fall ergeben: float(79,95). Typ wäre sicher Float, würde aber als eine Kommazahl repräsentiert (externe Repräsentation) - sogar bei var_dump().

Problematisch ist nun, falls -wie oben zu sehen- der key LC_NUMERIC auf eine Locale, oder ganz allgemein auf einen Wert gesetzt ist, welche die externe Repräsentation von Float auf Komma setzt. Hier in diesem Fall auf eine DE-locale, also auf eine externe Repräsentation mit Komma: LC_NUMERIC=de_DE.UTF-8.

Eine externe Repräsentation liegt nun wohl vor, falls eine Float Variable in PHP Methoden wie abs() oder round() gegeben wird.

// Auflisten aller PHP Locale Settings
echo setlocale(LC_ALL, 0) . "\n";

/* ergibt bspw.:
LC_CTYPE=en_US.UTF-8;LC_NUMERIC=de_DE.UTF-8;LC_TIME=de_DE.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=de_DE.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;LC_NAME=de_DE.UTF-8;LC_ADDRESS=de_DE.UTF-8;LC_TELEPHONE=de_DE.UTF-8;LC_MEASUREMENT=de_DE.UTF-8;LC_IDENTIFICATION=de_DE.UTF-8
*/

Lösung

Der Key LC_NUMERIC muss mit setlocale auf einen Wert gesetzt werden, welcher ermöglicht, dass die externe Repräsentation von Float in . Decimal dargestellt wird. Es reicht hier nicht, den Key LC_ALL zu setzen, wie Tests zeigten, sondern es muss explizit der Key LC_NUMERIC gesetzt werden. So kann es sein, dass LC_ALL den geänderten Wert darstellt, nicht aber jedoch LC_NUMERIC.

In Betracht kommen Locale-Angaben von Ländern, welche Floats auch üblicherweise mit . Decimal darstellen. USA etwa:

setlocale(LC_NUMERIC, 'en_US.UTF-8');

Empfehlung

Stattdessen kann aber auch schlicht C angegeben werden, welches PHP anweist, den C/C++ Float-Separator Typ zu benutzen, welcher . Decimal ist:

setlocale(LC_NUMERIC, 'C');

Links

Related

This website uses Cookies to provide you with the best possible service. Please see our Privacy Policy for more information. Click the check box below to accept cookies. Then confirm with a click on "Save".