Deal with numbers the right way in PHP
This library aims to deal with numbers like prices, weights and quantities the right way in PHP.
Have you ever worked with prices, weights, or any other numbers in PHP? What type are they? An integer? A string? Or did
you get a float to manage decimals? And how can you do calculations with them? We have all struggled with float’s counter-intuitive behavior.
Ahh, after hours of investigation you’ve found BC Math. Now you can do math
with your numbers. However, it is still hard to manage those numbers in your codebase. BC Math only accepts and returns
strings. Type hinting strings when working with numbers as a modern-php-techie is not done.
This library will help you to manage number in your codebase. Using the Number
class you can typehint them
(getTotal(Number $quantity)
) and make calculations on the number itself ($number->sum('200')'
). Since those methods
are immutable you can chain your methods on them.
This library aims to make your code cleaner. You can typehint the Number
class, and you can make cleaner calculations
(still using BC Math in the background).
We have chosen not to support specific implementations of numbers like money and weights. This is too specific and out of scope.
Mainly, custom implementations of numbers are business specific. In our opinion you should create them yourself, according
to the desired needs of your business.
You can install the package via composer:
composer require madebybob/php-number
In short, the Number\Number
class is where it’s all about. This is how you can create a Number
instance:
use Number\Number;
// with string
$number = new Number('200');
// with integer
$number = new Number(200);
// with float
$number = new Number(200.8);
// via static method
$quantity = Number::create(4);
// calculations
$total = $number->add($quantity);
Creating new numbers (or using them in the methods below) supports types like Number
, string, integer and float.
To add a new number to your current number instance:
$total = $number
->add('200')
->plus('200');
To subtract a number from your current number instance:
$total = $number
->subtract('200')
->sub('200') // sub is an alias for subtract
->minus('200'); // minus is an alias for subtract
To divide your current number instance into the given number:
$total = $number
->divide('200')
->div('200'); // div is an alias for divide
Division by zero is not possible, of course. To not break your chain, a fallback value can be used like this:
$total = $number->divide($variable, null, '1.000');
To multiply your current number instance with the given number:
$total = $number
->multiply('200')
->mul('200'); // mul is an alias for multiply
To get the modulus of the current number instance:
$newNumber = $number
->modulus('200')
->mod('200'); // mod is an alias for modulus
To get the square root of the current number instance:
$sqrt = $number
->sqrt()
->squareRoot(); // squareRoot is an alias for sqrt
To compare two numbers with each other, these helpers are available, which will return a bool
:
$number = new Number('200');
// check if the number is equal to x
$number->isEqual('200');
$number->eq('200');
// check if the number is positive
$number->isPositive();
// check if the number is negative
$number->isNegative();
// check if the number is greater than x
$number->isGreaterThan('100');
$number->gt('100');
// check if the number is greater than or equal to x
$number->isGreaterThanOrEqual('100');
$number->gte('100');
// check if the number is less than x
$number->isLessThan('300');
$number->lt('300');
// check if the number is less than or equal to x
$number->isLessThanOrEqual('300');
$number->lte('300');
// check if the number is zero ("0")
$number->isZero();
To get the absolute (positive) value of the current instance:
$number = new Number('-200');
// $absolute will be 200
$absolute = $number->absolute();
// abs is an alias for absolute
$abs = $number->abs();
To get the opposite value of the current instance:
$number = new Number('200');
// $absolute will be -200
$absolute = $number->opposite();
// opp is an alias for absolute
$abs = $number->opp();
To make sure the current number is not higher or lower than expected:
$number = new Number('200');
// $result will be 250
$result = $number->min('250');
// $result will be 100
$result = $number->max('100');
To use a min and max ‘clamp’ at the same time:
$number = new Number('200');
// $result will be 150
$result = $number->clamp('100', '150');
To round the current number instance, the following methods are available:
$number = new Number('200.5000');
// rounds the number to '201.0000'
$number->round();
// ceils the number to '201.0000'
$number->ceil();
// floors the number to '200.0000'
$number->floor();
Since the Number
class is immutable, most methods will return a new Number
instance.
$two = new Number(2);
$four = $two->plus(2);
echo $two->toString(); // $two is still 2
Because the mathematical methods are fluent, you will be able to chain your calculations like so:
$number = new Number('200');
$result = $number
->add(200)
->subtract(109.5)
->mul($two)
->toString();
We encourage you to create custom implementations of the AbstractNumber
class for your specific use cases. This enables
you to type hint much better which type of number you expect and how they should be formatted.
PHP Number - Examples is a repository dedicated to showing how a custom
number type like weights should be implemented. Please check out this repository for further documentation about the
extensibility of this package.
composer test
./vendor/bin/php-cs-fixer fix
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.