Folgendes Szenario: Ein Benutzer einer PHP-Applikation muss einen Geldbetrag eingeben. Für die Weiterberechnung und Speicherung dieses Betrages erwartet PHP ein Format wie 123 oder 567.89, nicht aber 246,80 oder 500,-.
Bevor dem Benutzer der Applikation lange Erklärungen geben, wie eine solche Eingabe auszusehen hat, sollten wir uns selbst um die Bereinigung der Geldbetrageingabe kümmern. Wenn der Benutzer allerdings wirklich Quatsch eingibt (etwa ‘foo,bar’) so sollte ein Wert von 0 bzw. 0.00 zurückgegeben werden.
Dafür habe ich diese Funktion erstellt:
function formatMoney($betrag) {
if(is_int($betrag)) return $betrag . '.00';
$sBetrag = ltrim($betrag, '0');
$sBetrag = strtr($sBetrag, array(',' => '.', ' ' => '.',));
$sBetrag = preg_replace('![^0-9.]!', '', $sBetrag);
$aBetrag = explode('.', $sBetrag);
if(isset($aBetrag[1])) {
$iCent = (int) trim(array_pop($aBetrag));
if(strlen($iCent) > 2) {
$aBetrag[] = $iCent;
$iCent = '00';
} elseif(empty($iCent)) {
$iCent = '00';
}
} else {
$iCent = '00';
}
$iEuro = (int) trim(implode($aBetrag));
if(strlen($iEuro) === 0) {
$iEuro = 0;
}
return $iEuro . '.' . $iCent;
}
Das sieht erstmal sehr unübersichtlich aus, jedoch kann ich hier eine Erläuterung geben:
In Zeile drei wird erfragt, ob es sich bei dem Betrag um einen Integerwert handelt. Wenn dies der Fall ist, so kann er gleich (mit Geldbetragsüblichen Nachkommastellen) zurückgegeben werden. Zeile fünf entfernt führende Nullen des Strings, Zeile sechs wandelt alle Kommata und Leerzeichen in Punkte um. Zeile sieben entfernt alle jetzt noch verbleibenden Zeichen, etwa Buchstaben – so haben wir am Ende eine Zahlenkolonne, die höchstens durch Punkte getrennt wird.
In Zeile 9 geht es eigentlich erst richtig los: Wir trennen die Zahlenkolonne anhand der Punkte und nehmen an, dass es sich bei dem letzten Glied um den Centbetrag handelt (Zeile 10), sofern es mehr als ein Glied erzeugt wurde. Ansonsten handelte es sich um einen glatten Betrag ohne Nachkommastelle (Zeile 19). Wenn das Teilstück, das wir als Centbetrag vermuten, allerdings länger als zwei Zeichen lang ist, so wird der Vorgang rückgängig gemacht und auf ’00′ gesetzt. Auch wenn vergessen wurde, ein Centbetrag anzugeben, wird automatisch ’00′ für den Centbetrag angesetzt (Zeile 12-17).
Jetzt fügen wir die verbleibenden Teilstücke einfach wieder zusammen und fügen den berechneten Centwert hinten dran (Zeile 25).
Und jetzt testen wir die Funktion:
echo formatMoney('0123,0'); // 123,0
echo formatMoney('01234.567.89,00'); // 123456789.00
echo formatMoney('9,870,99'); // 9870.99
echo formatMoney('0010 . 50'); // 10.50
echo formatMoney(987.654); // 987654.00
echo formatMoney('0900'); // 900.00
echo formatMoney('.55'); // 0.55
echo formatMoney('50.000,-'); // 50000.00
echo formatMoney('foo,bar'); // 0.00
echo formatMoney('6_500,- (und ein paar zerquetschte)'); // 6500.00
Klappt! Wahrscheinlich habe ich nicht alle Fälle berücksichtigt. Aber für den gewöhnlichen Einsatz ist diese Funktion sicher genau richtig. Wenn euch noch was ein- oder auffällt, schreibt es mir.
Inspiriert zu dieser Funktion hat mich dieser Thread im PHP-Forum.


