Releases: nanasess/bcmath-polyfill
v1.0.3
What's Changed
🐛 Bug Fixes
Fix Rector 2.4+ scoped polyfill collision with RoundingMode (#56, #57)
Prior releases failed with a fatal error in environments that dev-require rector/rector: ^2.4:
PHP Fatal error: Cannot declare enum RoundingMode, because the name is already
in use in /path/to/vendor/nanasess/bcmath-polyfill/lib/RoundingMode.php on line 16
Rector 2.4.0+ ships a scoped polyfill (vendor/rector/rector/vendor/symfony/polyfill-php84/Resources/RoundingMode.php) that declares a global class RoundingMode via class_alias on PHP < 8.4. The previous guard !enum_exists('RoundingMode') could not detect a preexisting class definition, so the polyfill tried to declare its enum on top of the class and crashed.
The guard was rewritten to !class_exists('RoundingMode', false), which correctly detects both:
- The native PHP 8.4+
RoundingModeenum (enums are reported as classes byclass_exists()since PHP 8.1) - Classes aliased into the global namespace by third-party scoped polyfills (Rector 2.4+, etc.)
The second argument false prevents autoload from triggering, so third-party stub files are not accidentally executed.
⚠️ Minor Behavior Change
bcpow() / bcpowmod() first parameter renamed to $num (#57)
The polyfill's bcpow() and bcpowmod() functions used $base as the first parameter, while the native PHP 8.1+ bcmath extension uses $num. These have been aligned.
- Positional argument calls (
bcpow('2', '10')): no impact. - Named argument calls (
bcpow(base: '2', exponent: '10')): update required — changebase:tonum:.
This change also corrects the argument name reported in ValueError messages (e.g. bcpow(): Argument #1 ($num) is not well-formed), which matches the native extension and is checked by the upstream php-src PHPT test suite.
🧪 Testing
- Added
tests/RoundingModeGuardTest.php— regression tests for the Rector scenario using isolated PHP subprocesses (required because Composer'sfilesautoload otherwise loads the polyfill before any test can simulate the "class already defined" precondition). - Added clean-load coverage for PHP 8.4+ environments (verifies the polyfill short-circuits correctly when the native
RoundingModeenum is present). - Subprocess runner now has a 10-second timeout (
stream_set_blocking+proc_get_statuspolling) so a hung fixture cannot stall CI.
🔧 Internal Improvements
phpstan.neon.dist: scopedignoreErrorsentries suppress false positives caused by PHPStan's Better Reflection picking up the Rector-scopedRoundingModeclass (instead of our enum) fromvendor/rector/rector/vendor/. Each entry is tagged with its identifier and linked back to issue #56 so it can be revisited once upstream Rector drops the scoped polyfill..php-cs-fixer.dist.php/rector.php: disableddeclare_strict_types/SafeDeclareStrictTypesRectorrules to preserve the existing test suite's intentional reliance on implicitint/bool→stringcoercion (matching native bcmath behavior).
🔗 Links
- Full Changelog: 1.0.2...1.0.3
- Issue: #56
- Pull Request: #57
👥 Contributors
v1.0.2
What's Changed
🚀 New Features
PHP 8.5 Support
- Add PHP 8.5 to CI/CD test matrix across all platforms (Ubuntu, Windows, macOS)
- Verified compatibility with PHP 8.5 for all bcmath polyfill functions
- Skip
gh20006test for PHP 8.5 (requiresBcMath\NumberOOP API not yet implemented in polyfill) - Update documentation to reflect PHP 8.5 support
Benchmarking Framework
- Add comprehensive performance benchmarking tool for comparing polyfill vs native bcmath
- Support multiple output formats: console, JSON, CSV, and Markdown
- GitHub Actions integration:
- PR Benchmarks: Comment
/benchmarkon PRs for quick performance tests (1,000 iterations) - Merge Benchmarks: Automatic full benchmark on PR merge (10,000 iterations)
- Manual Benchmarks: Trigger via GitHub Actions UI with customizable settings
- PR Benchmarks: Comment
- Test all bcmath operations with various number sizes and precision scales
🔧 Improvements
Code Quality
- Apply Rector code modernization rules:
- Use
in_array()with strict comparison - Adopt first-class callables syntax
- Enhance type safety throughout codebase
- Use
- Add explicit type declarations to all function parameters (
string,?int) - Remove redundant PHPDoc annotations
CI/CD Enhancements
- Fix PHPStan configuration for
expr.resultUnusederror handling - Improve workflow reliability with file-based approach for PR comments
- Fix backtick escaping in benchmark comment formatting
- Remove redundant condition checks in workflows
Documentation
- Add comprehensive performance benchmarking guide to README
- Document GitHub Actions benchmark workflows
- Update supported PHP versions list (8.1, 8.2, 8.3, 8.4, 8.5)
📊 Testing
All 57 CI checks passing across:
- 3 operating systems (Ubuntu, Windows, macOS)
- 5 PHP versions (8.1, 8.2, 8.3, 8.4, 8.5)
- With and without bcmath extension
- Docker PHPT tests using official PHP test suite
🔗 Links
- Full Changelog: 1.0.1...1.0.2
- Benchmark Documentation: See README.md "Performance" section
- PHP 8.5 CI Results: All tests passing ✅
👥 Contributors
v1.0.1
What's Changed
- Fix zero handling in BCMath division and power operations by @nanasess in #31
- Fix BCMath::sqrt negative validation and algorithm precision issues by @nanasess in #32
- ci(deps): bump stefanzweifel/git-auto-commit-action from 5 to 6 by @dependabot[bot] in #33
- chore: remove legacy configuration files by @nanasess in #34
- Add PHP 8.4 RoundingMode enum support with polyfill compatibility by @nanasess in #35
- feat: Add Docker-based PHPT test runner for comprehensive bcmath polyfill testing by @nanasess in #37
- feat: comprehensive Docker PHPT test infrastructure and BCMath improvements by @nanasess in #38
Full Changelog: 1.0.0...1.0.1
v1.0.0
What's Changed
- docs: add comparison with phpseclib/bcmath_compat to README by @nanasess in #16
- ci(github): add Dependabot configuration for Composer and GitHub Actions by @nanasess in #18
- feat: add comprehensive development tools and improve code quality by @nanasess in #20
- Add tests for BCMath polyfill without bcmath extension by @nanasess in #22
- Add Claude Code GitHub Workflow by @nanasess in #24
- ci(deps): bump actions/checkout from 4 to 5 by @dependabot[bot] in #19
- refactor(BCMath): major architecture refactoring with DRY principle and unified structure by @nanasess in #25
- Add PHP-src BCMath Tests Integration by @nanasess in #27
- Major BCMath Architecture Improvements - Issue #26 by @nanasess in #28
- feat: implement comprehensive ValueError validation for bcmath functions (resolves #12) by @nanasess in #29
New Contributors
- @dependabot[bot] made their first contribution in #19
Full Changelog: 0.0.1...1.0.0
v0.0.1
bcmath-polyfill v0.0.1
The first stable release of bcmath-polyfill, a fork of phpseclib/bcmath_compat with groundbreaking PHP 8.4 support and enhanced functionality.
🔄 Key Differences from phpseclib/bcmath_compat
🆕 PHP 8.4 Support (Major Enhancement)
bcmath-polyfill is the FIRST and ONLY bcmath polyfill supporting PHP 8.4's new functions:
bcfloor()- Round down to nearest integerbcceil()- Round up to nearest integerbcround()- Round to specified precision with multiple rounding modes- Supports all PHP rounding modes: HALF_UP, HALF_DOWN, HALF_EVEN, HALF_ODD
- Handles negative scale parameters correctly
🐛 Bug Fixes and Improvements
- Fixed bcscale() state pollution in test environments
- Fixed PHP 8.2+ deprecation warnings for dynamic properties
- Improved error handling with proper PHP version detection
- Enhanced scale parameter handling for more consistent behavior
📦 Package and Maintenance
- Actively maintained with regular updates
- Modern CI/CD with GitHub Actions including PHP 8.4 in test matrix
- Renamed package from
phpseclib/bcmath_compattonanasess/bcmath-polyfill - Enhanced documentation with comprehensive README and examples
🚀 Performance and Compatibility
- Same lightweight approach - Zero production dependencies beyond phpseclib
- 100% backward compatible - Drop-in replacement for phpseclib/bcmath_compat
- PHP 8.1+ focused - Optimized for modern PHP versions
📊 Comparison Table
| Feature | phpseclib/bcmath_compat | bcmath-polyfill v0.0.1 |
|---|---|---|
| PHP 8.4 functions | ❌ Not supported | ✅ Full support |
| bcfloor() | ❌ | ✅ |
| bcceil() | ❌ | ✅ |
| bcround() | ❌ | ✅ |
| PHP 8.2+ deprecations | ✅ Fixed | |
| Test suite pollution | ✅ Fixed | |
| Active maintenance | ❌ Limited | ✅ Active |
| CI/CD (PHP versions) | GitHub Actions (8.1, 8.2, 8.3) | GitHub Actions (8.1, 8.2, 8.3, 8.4) |
🔧 Migration Guide
Switching from phpseclib/bcmath_compat is seamless:
# Remove old package
composer remove phpseclib/bcmath_compat
# Install bcmath-polyfill
composer require nanasess/bcmath-polyfillNo code changes required - all existing functions work identically, plus you get PHP 8.4 features!
✨ New PHP 8.4 Function Examples
// New in PHP 8.4 - Only available in bcmath-polyfill!
$floor = bcfloor('2.9'); // "2"
$ceil = bcceil('2.1'); // "3"
$rounded = bcround('3.14159', 2); // "3.14"
$rounded_half_down = bcround('2.55', 1, PHP_ROUND_HALF_DOWN); // "2.5"🎯 Why Choose bcmath-polyfill?
- Future-proof - Ready for PHP 8.4 today
- Battle-tested - Built on phpseclib's proven foundation
- Actively maintained - Regular updates and bug fixes
- Community-driven - Open to contributions and feedback
📦 Installation
composer require nanasess/bcmath-polyfill👥 Credits
- Jim Wigginton - Original phpseclib/bcmath_compat author
- Kentaro Ohkouchi (@nanasess) - Fork maintainer and PHP 8.4 implementation
📄 License
MIT License
Full Changelog: Forked from phpseclib/bcmath_compat with 23 new commits
Repository: https://github.com/nanasess/bcmath-polyfill