PHP package for dealing with different formats of betting odds: decimal (European), fractional (British), and moneyline (American).
This library has been completely redesigned with:
- Immutable
Oddsclass containing all formats and probability (not meant for direct instantiation - useOddsFactory) OddsFactorywith dependency injection for conversion strategies- String-based decimals for precision and security (no more float issues!)
- bcmath calculations for exact mathematical operations
- Extensible odds ladder system via interfaces
- Fixed precision integer support for performance-critical applications
- ✅ Precision: String-based decimals with bcmath calculations
- ✅ Immutable design: Thread-safe odds objects
- ✅ All-in-one: Single object contains decimal, fractional, moneyline, and probability
- ✅ Dependency injection: Configurable conversion strategies
- ✅ Extensible: Custom odds ladder implementations
- ✅ Comprehensive: Full test coverage
- PHP 8.4+ (required for bcmath precision functions)
- bcmath extension (standard in most installations)
- Composer
composer require gryfoss/oddsrequire 'vendor/autoload.php';
use GryfOSS\Odds\OddsFactory;
$factory = new OddsFactory();
// Create from string decimal (secure, precise)
$odds = $factory->fromDecimal('2.50');
echo $odds->getDecimal(); // "2.50"
echo $odds->getFractional(); // "3/2"
echo $odds->getMoneyline(); // "+150"
echo $odds->getProbability(); // 40 (integer percentage)$factory = new OddsFactory();
// From decimal
$odds = $factory->fromDecimal('1.75');
// From fractional
$odds = $factory->fromFractional(3, 4);
// From moneyline
$odds = $factory->fromMoneyline('-133');
// From fixed precision integer (advanced usage)
$odds = $factory->fromFixedPrecision(250); // Represents 2.50use GryfOSS\Odds\Utils\OddsLadder;
$oddsLadder = new OddsLadder();
$factory = new OddsFactory($oddsLadder);
$odds = $factory->fromDecimal('2.00');
echo $odds->getFractional(); // Uses odds ladder lookupuse GryfOSS\Odds\Utils\OddsLadder;
class MyCustomLadder extends OddsLadder
{
protected function getLadder(): array
{
return [
'1.50' => 'evens',
'2.00' => '1/1',
'3.00' => '2/1',
];
}
}
$factory = new OddsFactory(new MyCustomLadder());
$odds = $factory->fromDecimal('1.90');
echo $odds->getFractional(); // "evens"For performance-critical applications, you can work directly with fixed precision integers (decimal * 100):
$factory = new OddsFactory();
// Create from already prepared integer (2.50 = 250)
$odds = $factory->fromFixedPrecision(250);
echo $odds->getDecimal(); // "2.50"
echo $odds->getFixedPrecisionOdds(); // 250
// Useful for database storage or API responses
$integerOdds = $odds->getFixedPrecisionOdds(); // Store as integer
$restoredOdds = $factory->fromFixedPrecision($integerOdds); // Restore laterSee STRING_DECIMAL_GUIDE.md for detailed migration instructions.
Key Changes:
- Use
OddsFactoryinstead of individual odd classes - Pass decimals as strings:
'2.50'instead of2.50 - All return values are strings for precision (except
getProbability()which returns integer) - Single
Oddsobject contains all formats Oddsclass is immutable and should not be instantiated directly
- String Decimal Guide - Precision and migration
- NEW_API.md - Complete API documentation
This is an open-sourced software licensed under the MIT license.