madebybob / php-number
Deal with numbers the right way
Installs: 7 169
Dependents: 1
Suggesters: 0
Security: 0
Stars: 99
Watchers: 3
Forks: 3
Open Issues: 1
Requires
- php: ^7.4|^8.0
- ext-bcmath: *
- ext-json: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpro/grumphp: ^1.0
- phpunit/phpunit: ^9.3
- symfony/var-dumper: ^5.1
- vimeo/psalm: ^4.0
README
This library aims to deal with numbers like prices, weights and quantities the right way in PHP.
The problem
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.
The solution
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.
Scope
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.
Table of Contents
Installation
You can install the package via composer:
composer require madebybob/php-number
Usage
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.
Add
To add a new number to your current number instance:
$total = $number ->add('200') ->plus('200');
Subtract
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
Divide
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');
Multiply
To multiply your current number instance with the given number:
$total = $number ->multiply('200') ->mul('200'); // mul is an alias for multiply
Modulus
To get the modulus of the current number instance:
$newNumber = $number ->modulus('200') ->mod('200'); // mod is an alias for modulus
Square root
To get the square root of the current number instance:
$sqrt = $number ->sqrt() ->squareRoot(); // squareRoot is an alias for sqrt
State & Comparison
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();
Absolute & opposite values
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();
Limiting values
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');
Rounding
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();
Immutable & Chaining
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();
Extensibility
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.
Testing & Php CS Fixer
composer test
./vendor/bin/php-cs-fixer fix
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Supporters
Credits
License
The MIT License (MIT). Please see License File for more information.