Overview
MongoDB 3.4 introdujo compatibilidad con el tipo BSON decimal128, que es un valor de punto flotante decimal de 128bits capaz de emular el redondeo decimal con precisión exacta. Esta funcionalidad está diseñada para aplicaciones que manejan datos monetarios, como cálculos financieros y tributarios.
El MongoDB\BSON\Decimal128 clase puede utilizarse para trabajar con este tipo en PHP.
Trabajar con valores Decimal128
Insertar un Decimal128
El siguiente ejemplo inserta un valor de tipo Decimal128 en el campo price de una colección llamada inventory:
$collection = (new MongoDB\Client)->test->inventory; $collection->insertOne([ '_id' => 1, 'item' => '26-inch monitor', 'price' => new MongoDB\BSON\Decimal128('428.79'), ]); $item = $collection->findOne(['_id' => 1]); var_dump($item);
La vista de salida se ilustraría como sigue:
object(MongoDB\Model\BSONDocument)#9 (1) { ["storage":"ArrayObject":private]=> array(3) { ["_id"]=> int(1) ["item"]=> string(15) "26-inch monitor" ["price"]=> object(MongoDB\BSON\Decimal128)#13 (1) { ["dec"]=> string(6) "428.79" } } }
Operaciones matemáticas con BCMath
La extensión no proporciona ninguna funcionalidad para trabajar con valores Decimal128; sin embargo, la representación en string de un MongoDB\BSON\Decimal128 objeto puede ser utilizada con la extensión BCMath de PHP.
El siguiente ejemplo suma dos valores de Decimal128 y crea un nuevo valor de Decimal128 con el resultado de bcadd():
$lhs = new MongoDB\BSON\Decimal128('1.234'); $rhs = new MongoDB\BSON\Decimal128('5.678'); $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs)); var_dump($sum);
La vista de salida se ilustraría como sigue:
object(MongoDB\BSON\Decimal128)#4 (1) { ["dec"]=> string(1) "6" }
Esto no coincide con el resultado esperado de "6.912". Cada operación de la API de BCMath utiliza una escala para determinar el número de dígitos decimales del resultado. La escala predeterminada es cero, por lo que el ejemplo anterior produce un resultado sin precisión decimal.
En el siguiente ejemplo, utilizamos una escala de tres para bcadd() para obtener el resultado esperado:
$lhs = new MongoDB\BSON\Decimal128('1.234'); $rhs = new MongoDB\BSON\Decimal128('5.678'); $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs, 3)); var_dump($sum);
La vista de salida se ilustraría como sigue:
object(MongoDB\BSON\Decimal128)#4 (1) { ["dec"]=> string(5) "6.912" }
En lugar de especificar una escala para cada operación, se puede establecer una escala por defecto mediante bcscale() o la configuración INI de bcmath.scale. El tipo Decimal128 admite hasta 34 dígitos decimales (es decir, dígitos significativos).