php-decimal/stubs
IDE and static analysis stubs for the PHP Decimal extension. Provides PHP method/function signatures to improve autocompletion and type checking without requiring the extension source. For installing the actual extension, see php-decimal/php-decimal.
Install the Core Dependency
First, install the php-decimal/php-decimal package (this package provides the actual Decimal class):
composer require php-decimal/php-decimal
Add Stubs Install the stubs package to enable IDE autocompletion and static analysis:
composer require --dev php-decimal/stubs
Trigger Stub Loading
Run composer dump-autoload to ensure stubs are loaded:
composer dump-autoload
Verify in IDE
Open a PHP file and type new \Decimal\Decimal(...)—your IDE (PHPStorm, VSCode with Intelephense) should now show method autocompletion.
use Decimal\Decimal;
$price = new Decimal('19.99');
$taxRate = new Decimal('0.0725'); // 7.25%
$total = $price->multiply($taxRate)->add($price);
echo $total; // Outputs: 21.44 (with precision handling)
Why? Stubs ensure your IDE validates method calls like multiply() and add() without runtime errors.
Use with PHPStan/Psalm:
Configure your static analyzer to recognize Decimal as a custom type. Example PHPStan config:
includes:
- vendor/php-decimal/stubs/Decimal.stub
Now, tools will flag invalid operations (e.g., $decimal->concat()).
Return Type Declarations:
function calculateTotal(array $items): Decimal {
return array_reduce($items, fn(Decimal $carry, array $item) => $carry->add($item['price']), new Decimal('0'));
}
Form Request Validation:
Use Decimal in validation rules (via custom rules or Illuminate\Validation\Rule):
use Decimal\Decimal;
$validator->validate([
'price' => new Decimal($request->price),
], [
'price' => ['required', function (string $attribute, mixed $value, Closure $fail) {
if (!($value instanceof Decimal)) {
$fail('The '.$attribute.' must be a valid decimal.');
}
}],
]);
Model Attributes:
Cast attributes to Decimal in Eloquent models:
protected $casts = [
'price' => Decimal::class,
];
Note: Requires custom accessors/mutators if using Laravel < 8.x.
Consistent Precision: Set a default precision in a service class:
class MoneyService {
public function __construct(private Decimal $precision) {}
public function format(Decimal $amount): string {
return $amount->toScale($this->precision->value)->toString();
}
}
Stubs Benefit: IDE will autocomplete toScale() and toString().
Avoiding Floating-Point Pitfalls:
Replace float with Decimal in calculations:
// Bad: Floating-point inaccuracy
$total = $subtotal + ($subtotal * 0.0725);
// Good: Precise arithmetic
$total = $subtotal->add($subtotal->multiply($taxRate));
Decimal::fromFloat() for test data:
$this->assertEquals(
new Decimal('19.99'),
Decimal::fromFloat(19.99)->toScale(2)
);
Stubs Benefit: IDE shows fromFloat() as a valid static method.Stub Loading Failures
Class 'Decimal\Decimal' not found or no autocompletion.composer dump-autoload is run after installing stubs.Settings > PHP > Include Path and add:
vendor/php-decimal/stubs
Ctrl+Shift+P > "Intelephense: Restart Server").Precision Mismatches
Decimal::fromFloat(0.1) may not equal new Decimal('0.1') due to floating-point representation.toScale():
$decimal = new Decimal('0.1'); // Exact
// or
$decimal = Decimal::fromFloat(0.1)->toScale(1);
Static Analysis False Positives
Decimal methods as undefined.Laravel Cache Issues
Decimal behavior.php artisan cache:clear
php artisan view:clear
IDE-Specific Tricks
Settings > Languages & Frameworks > PHP for better stub integration.Ctrl+Space to trigger autocompletion after typing new Decimal(.settings.json:
"intelephense.stubs": ["vendor/php-decimal/stubs"]
Performance Considerations
Decimal: For simple cases (e.g., counters), stick with int. Use Decimal only for monetary/precise values.Decimal values, consider using Decimal::fromFloat() in bulk and converting to strings for storage (e.g., in a database).Extending Functionality
trait MoneyMethods {
public function toCurrency(string $currency = 'USD'): string {
return sprintf('%s %s', $currency, $this->toScale(2));
}
}
Stubs Workaround: IDE won’t autocomplete trait methods—document them in PHPDoc blocks.Debugging
function ddDecimal(Decimal $decimal) {
dump([
'value' => $decimal->toString(),
'scale' => $decimal->scale(),
'precision' => $decimal->precision(),
]);
}
Division by zero: Use Decimal::fromFloat(0) instead of new Decimal('0') for safety.Invalid argument: Ensure inputs to Decimal are strings or numeric strings (e.g., '19.99' not 19.99).CI/CD Integration
# Example GitHub Actions step
- name: Run PHPStan
run: vendor/bin/phpstan analyse --level=5 --include-paths=vendor/php-decimal/stubs src/
How can I help you explore Laravel packages today?