A universal PHP library for converting and manipulating values with units of measurement including money, weight, length, temperature, volume, area, and more. Features smart parsing, arithmetic operations, unit conversion, and flexible output formatting.
composer require jbzoo/simpletypes
- Smart Parser: Handles various input formats, decimal symbols, whitespace, and case variations
- Type System: Built-in support for Money, Weight, Length, Temperature, Volume, Area, Time, Info, and Degree
- Arithmetic Operations: Add, subtract, multiply, divide with automatic unit conversion
- Method Chaining: Fluent interface for complex calculations
- Flexible Output: Text, HTML, and input field rendering with customizable formatting
- Configuration: Extensible configuration system for custom types and conversion rules
- Debug Support: Built-in logging and debugging capabilities
use JBZoo\SimpleTypes\Config;
use JBZoo\SimpleTypes\Money;
use JBZoo\SimpleTypes\ConfigMoney;
// Set config object for all Money objects as default
Config::registerDefault('money', new ConfigMoney());
// Create objects with automatic parsing
$money = new Money('10 eur');
$weight = new Weight('1000'); // Gram is default unit
$length = new Length('500 km');
$money = new Money('100500 usd', new ConfigMoney()); // Custom configuration
SimpleTypes comes with comprehensive configurations for common measurement types:
- Area - Square meters, feet, acres, hectares, etc.
- Degree - Angular measurements (degrees, radians)
- Info - Digital storage (bytes, KB, MB, GB, TB)
- Length - Meters, feet, miles, kilometers, etc.
- Money - Currency conversion and formatting
- Temperature - Celsius, Fahrenheit, Kelvin, Rankine
- Time - Seconds, minutes, hours, days, etc.
- Volume - Liters, gallons, cubic meters, etc.
- Weight - Grams, kilograms, pounds, ounces, etc.
Custom types can be easily created by extending the base configuration classes.
The parser automatically handles various input formats and edge cases:
$money = new Money(' - 1 2 3 , 4 5 6 rub '); // Parses to -123.456 rubles
$money = new Money('1.0e+18 EUR '); // Scientific notation support
$money = new Money(' EuR 3,50 '); // Case insensitive, handles whitespace
$money = new Money('usd'); // Creates zero-value USD object
Perform complex calculations with fluent interface:
$value = (new Money('4.95 usd'))
->add('10 usd') // $14.95
->subtract('2 eur') // $10.95
->negative() // -$10.95
->getClone() // copy of object is created
->division(5) // -$2.19
->multiply(10) // -$21.90
->convert('eur') // -10.95€ (For easy understanding we use 1 EUR = 2 USD)
->customFunc(function (Money $value) { // sometimes we would like something more than plus/minus ;)
$value
->add(new Money('600 rub')) // 1.05€ (1 EUR = 50 RUB)
->add('-500%'); // -4.2€
})
->abs(); // 4.2€
Multiple ways to perform calculations:
// Using objects
$usd = new Money('10 usd');
$usd->add(new Money('10 eur'));
// Method chaining
$usd = (new Money('10 usd'))->add(new Money('10 eur'));
// String input with automatic parsing
$usd->add('10 eur');
// Using default unit from configuration
$usd->add('10');
// Array format
$usd->add(['10', 'eur']);
Supported Operations:
- Addition and subtraction with automatic unit conversion
- Multiplication and division
- Custom functions via closures
- Sign operations (negative, positive, absolute value)
- Percentage calculations
- Value and unit modifications
- Object cloning
- Unit/currency conversion
- Rounding and formatting
- Comparison operations
- Serialization support
Compare values with automatic unit conversion:
$kg = new Weight('1 kg'); // one kilogram
$lb = new Weight('2 lb'); // two pounds
var_dump($kg->compare($lb)); // false ("==" by default)
var_dump($kg->compare($lb, '==')); // false
var_dump($kg->compare($lb, '<')); // false
var_dump($kg->compare($lb, '<=')); // false
var_dump($kg->compare($lb, '>')); // true
var_dump($kg->compare($lb, '>=')); // true
Using string input with smart parsing:
$kg = new Weight('1 kg');
$lb = new Weight('2 lb');
var_dump($kg->compare('1000 g')); // true
var_dump($kg->compare('2 lb', '==')); // false
var_dump($kg->compare('2 lb', '<')); // false
var_dump($kg->compare('2 lb', '<=')); // false
var_dump($kg->compare('2 lb', '>')); // true
var_dump($kg->compare('2 lb', '>=')); // true
Calculate percentage differences between values:
$origPrice = new Money('100 usd');
$realPrice = new Money('40 eur');
$diff = $realPrice->percent($origPrice);
echo $diff->text(); // 80%
$discount = $realPrice->percent($origPrice, true); // revert flag added
echo $discount->text(); // 20%
Serialization Support:
$valBefore = $this->val('500 usd');
$valString = serialize($valBefore);
$valAfter = unserialize($valString)->convert('eur');
$valBefore->compare($valAfter);// true
String Conversion:
$val = $this->val('500 usd');
echo $val; // "$500.00"
Object Invocation:
$val = $this->val('10 eur');
// Convert to different currency
$val('usd'); // Converts to USD using exchange rates
// Set new value and currency
$val('100 rub');
$val('100', 'uah');
$value = new Money('-50.666666 usd');
echo $value->text(); // "-$50.67"
echo $value->text('rub'); // "-1 266,67 руб." (convert for display only)
echo $value->noStyle('rub'); // "-1 266,67" (number without currency symbol)
echo (new Money('-50.666666 usd'))->html('rub'); // HTML with data attributes for JavaScript
Generated HTML (formatted for readability):
<span
class="simpleType simpleType-block simpleType-money"
data-simpleType-id="1"
data-simpleType-value="-1266.66665"
data-simpleType-rule="rub"
data-simpleType-orig-value="-50.666666"
data-simpleType-orig-rule="usd">
-<span class="simpleType-value">1 266,67</span>
<span class="simpleType-symbol">руб.</span>
</span>
echo $value->htmlInput('rub', 'input-name-attr');
Generated HTML (formatted for readability):
<input
value="-1 266,67"
name="input-name-attr"
type="text"
class="simpleType simpleType-money simpleType-input"
data-simpleType-id="1"
data-simpleType-value="-1266.66665"
data-simpleType-rule="rub"
data-simpleType-orig-value="-50.666666"
data-simpleType-orig-rule="usd"
/>
Note: The HTML output includes extensive data attributes to enable client-side JavaScript operations without server round-trips.
Create custom types by extending the base configuration class. Here's an example for digital storage:
/**
* Example: Digital storage configuration
*/
class ConfigInfo extends Config
{
// Default unit for parsing
public $default = 'byte';
// Enable debug logging
public $isDebug = true;
// Define conversion rules and formatting
public function getRules()
{
return [
'byte' => [
'rate' => 1 // Base unit
],
'kb' => [
'symbol' => 'KB', // Display symbol
'round_type' => Formatter::ROUND_CLASSIC, // Rounding method
'round_value' => Formatter::ROUND_DEFAULT, // Decimal precision
'num_decimals' => '2', // Decimal places
'decimal_sep' => '.', // Decimal separator
'thousands_sep' => ' ', // Thousands separator
'format_positive' => '%v %s', // Positive format (%v=value, %s=symbol)
'format_negative' => '-%v %s', // Negative format
'rate' => 1024, // Conversion rate from base unit
],
'mb' => [
'symbol' => 'MB',
'rate' => 1024 * 1024,
],
'gb' => [
'symbol' => 'GB',
'rate' => 1024 * 1024 * 1024,
],
'bit' => [
'symbol' => 'Bit',
'rate' => function ($value, $to) { // Custom conversion function
return ($to === 'bit') ? $value * 8 : $value / 8;
},
],
];
}
}
// Create configuration instance
$config = new ConfigInfo();
// Register as default for all Info objects
Config::registerDefault('info', $config);
$info1 = new Info('700 MB');
$info2 = new Info('1.4 GB');
// Or pass configuration directly
$info1 = new Info('700 MB', $config);
$info2 = new Info('1.4 GB', $config);
// Perform calculations
echo $info2->subtract($info1)->dump() . PHP_EOL;
echo $info2->convert('mb')->dump() . PHP_EOL;
print_r($info2->logs());
Output:
0.71640625 gb; id=4
733.6 mb; id=4
Array
(
[0] => Id=4 has just created; dump="1.4 gb"
[1] => Subtract "700 mb"; New value = "0.71640625 gb"
[2] => Converted "gb"=>"mb"; New value = "733.6 mb"; 1 gb = 1024 mb
)
Track all operations performed on an object:
print_r($value->logs());
/**
* Array
* (
* [0] => Id=16 has just created; dump="4.95 usd"
* [1] => Add "10 usd"; New value = "14.95 usd"
* [2] => Subtract "2 eur"; New value = "10.95 usd"
* [3] => Set negative; New value = "-10.95 usd"
* [4] => Cloned from id=16 and created new with id=19; dump=-10.95 usd
* [5] => Division with "5"; New value = "-2.19 usd"
* [6] => Multiply with "10"; New value = "-21.9 usd"
* [7] => Converted "usd"=>"eur"; New value = "-10.95 eur"; 1 usd = 0.5 eur
* [8] => --> Function start
* [9] => Add "600 rub"; New value = "1.05 eur"
* [10] => Add "-500 %"; New value = "-4.2 eur"
* [11] => <-- Function finished; New value = "-4.2 eur"
* [12] => Set positive/abs; New value = "4.2 eur"
* )
*/
Access raw internal data without formatting:
echo $value->dump(); // "4.2 eur; id=19"
echo $value->getId(); // "19"
echo $value->val(); // "4.2"
echo $value->rule(); // "eur"
- PHP 8.2 or higher
- jbzoo/utils ^7.3
MIT License. See LICENSE file for details.