Práca s peňažnými hodnotami v PHP

, Štítky: PHP, Peniaze

Bill Karwin raz zavtipkoval na Twitteri, že ak by mal desať centov, vždy keď vidí ako niekto používa float na prácu s peňaznými hodnotami mal by 999.997634 dolárov. Narážal síce na MySQL, ale je to problém u mnoho programovacích jazykov.

Cent sem, cent tam

Práca s reálnymi číslami v PHP je problematická. Vedeli ste, že v PHP (.1 + .2 !== .3)? Vážne. Reálne čísla sú nepresné – upozorňuje na to aj PHP dokumentácia. Reálne čísla nemajú pevne stanovný počet desatinných miest. A tak by sa vám mohlo stať, že by ste pracovali so zlomkami centov. Dostali by ste sa aj do logických chýb — napríklad budete potrebovať rozdeliť zisk 1 € (slovom jedno euro) medzi troch akcionárov. Spravíte 1/3 ≐ 0,33, a každému vyplatíte 33 centov. Lenže jeden cent vám zostane.

Eurá, koruny…?

Navyše pokiaľ je čiastka vyjadrená iba ako číslo, skôr či neskôr narazíte na problémy. Predstavte si, že máte aplikáciu kde ukladáte účtovné doklady. Rozpadne eurozóna a Slovensko sa vráti ku korune. Alebo optimistickejšie, doklady sú v Českých korunách a Česko prijme EURO. Ktoré doklady sú v akej mene?

Ide to aj lepšie

Návrhový vzor ako pracovať s peňažnými hodnotami rozvinul Martin Fowler v knihe Patterns of Enterprise Application Architecture. Hodnoty sa vyjadrujú ako Immutable Value Object, ktorý obsahuje číselnú hodnotu v najmenšej peňažnej jednotke (cent, halier, kopejka…) a označenie meny. V PHP je k dispozícii knižnica Money, ktorá tento návrhový vzor implementuje.

Pre jednoduchšie použitie v Symfony aplikáciách som napísal jednoduchý bundle, ktorý túto knižnicu integruje ako Doctrine typ, formulárový prvok a obsahuje aj rozšírenie pre Twig šablóny.

← Späť na zoznam