nanasess/bcmath-polyfill
Pure-PHP polyfill for PHP's bcmath extension, providing bcadd, bcmul and the rest of the arbitrary-precision math functions when the native extension isn't installed. Drop-in compatibility for libraries and apps that rely on bcmath, with no server configuration changes needed.
Roadmap: where our product must run. This package answers a specific go-to-market question: can we ship to environments where we can't install PHP extensions? If part of our addressable market is cheap shared hosting, managed WordPress-adjacent platforms, locked-down enterprise PHP images, or serverless/PaaS runtimes with a fixed extension set, this is the difference between "supported deployment target" and "won't install." That's a distribution decision, not a code decision — and it belongs on the roadmap next to our hosting/compatibility matrix.
Build vs. buy: do we require ext-bcmath or ship a fallback? The default PM answer should be require the extension — it's bundled with PHP, it's one docker-php-ext-install bcmath or one composer.json platform requirement away, and it's 10–100x faster than pure PHP. This package only earns its place when we can prove at least one real deploy target can't enable the extension. Treat it as insurance for a specific segment, not a default dependency.
Feature decisions it unblocks:
bcadd()/bcmul() as global functions and simply fatal without the extension. That's the sharpest use case: we can't patch vendor code, so we polyfill the function namespace underneath it.What it explicitly does not decide: it isn't a general "we need decimal math" answer. If we're writing the math ourselves, brick/math is the better-maintained, better-API choice. This package's only unique value is drop-in global function compatibility with the bc* signatures (including PHP 8.4's new rounding helpers), so unmodified third-party code keeps working.
Risk decisions it forces. At 2 stars and 0 dependents with a single maintainer, adopting this is a supply-chain decision, not just a technical one. Decide up front: pin exact version, add to SBOM, write our own conformance tests against ext-bcmath output, and accept the option of vendoring/forking (MIT makes that cheap).
Consider it when all of these hold:
ext-bcmath — verified, not assumed (php -m | grep bcmath, check Dockerfile/CI matrix, check the host's extension list).bcadd/bcmul/bccomp as global functions, so we can't swap in an object-oriented library.bcfloor/bcceil/bcround behavior); otherwise phpseclib/bcmath_compat — which this package is derived from — is the more established ancestor.Look elsewhere when:
ext-bcmath and delete the whole category of problem.brick/math (maintained, typed, well-tested, huge adoption) rather than polyfilling global functions.To executives (one paragraph): Some of our target customers run our product on hosting where PHP's math extension can't be installed — and without it, payment and invoice calculations either break outright or fall back to floating point, which silently produces rounding errors in money. This is a small, MIT-licensed, drop-in compatibility layer that lets the same code run correctly in those environments, so we can support that segment without maintaining a fork of our billing path. It's a low-cost enabler for a distribution decision, not a platform bet; the main trade-off is that it's an early-stage open-source dependency we'd pin, test, and be ready to vendor — a few days of engineering, no licensing cost.
To engineering (the practical case): Pure-PHP implementations of bcadd, bcsub, bcmul, bcdiv, bcmod, bcpow, bcsqrt, bccomp, bcscale, plus PHP 8.4's new rounding functions — same signatures, no extension, no compilation. Drop it in for environments lacking ext-bcmath, keep ext-bcmath required everywhere else so production stays on the fast C path. Do three things before merge: (1) a conformance test comparing every function's output against native bcmath across a fixture set including negative numbers, scale edge cases, division by zero, and huge operands; (2) a performance benchmark on our realistic worst-case batch to confirm request budgets hold; (3) pin the exact version, add it to the SBOM, and note that upstream is a single maintainer derived from phpseclib/bcmath_compat — so we can fork or swap to that ancestor if needed. Also gate it: only load the polyfill when !extension_loaded('bcmath'), and fail loudly in dev if a code path unexpectedly hits the slow implementation in a hot loop.
Bottom line for the go/no-go: adopt only as a scoped fallback for a proven, extension-less deployment target, with a conformance suite and a pin. Not as a default dependency, and not as our decimal-math strategy.
How can I help you explore Laravel packages today?