Eu herdei uma pilha enorme de código legado escrito em PHP em cima de um banco de dados MySQL. O que notei é que o aplicativo usa doubles
para armazenamento e manipulação de dados.
Agora me deparei com vários posts mencionando como double
não são adequados para operações monetárias por causa dos erros de arredondamento. No entanto, ainda não encontrei uma solução completa sobre como os valores monetários devem ser tratados no código PHP e armazenados em um banco de dados MySQL.
Existe uma prática recomendada quando se trata de lidar com dinheiro especificamente em PHP?
O que estou procurando são:
- Como os dados devem ser armazenados no banco de dados? tipo de coluna? Tamanho?
- Como os dados devem ser tratados em adição normal, subtração. multiplicação ou divisão?
- Quando devo arredondar os valores? Quanto arredondamento é aceitável, se houver?
- Existe uma diferença entre lidar com valores monetários grandes e valores baixos?
Nota: Um exemplo de código MUITO simplificado de como posso encontrar valores monetários na vida cotidiana (várias preocupações de segurança foram ignoradas para simplificação. É claro que na vida real eu nunca usaria meu código como este):
$a= $_POST['price_in_dollars']; //-->(ex: 25.06) will be read as a string should it be cast to double?
$b= $_POST['discount_rate'];//-->(ex: 0.35) value will always be less than 1
$valueToBeStored= $a * $b; //--> any hint here is welcomed
$valueFromDatabase= $row['price']; //--> price column in database could be double, decimal,...etc.
$priceToPrint=$valueFromDatabase * 0.25; //again cast needed or not?
Espero que você use esse código de exemplo como um meio de trazer mais casos de uso e não interpretá-lo literalmente, é claro.
Pergunta sobre bônus Se eu devo usar um ORM como Doctrine ou PROPEL, quão diferente será usar dinheiro no meu código.
decimal
tipo em C # tem precisão limitada, mas é perfeitamente adequado para valores monetários.