dg/bypass-finals
Removes final keyword from source code on-the-fly and allows mocking of final methods and classes
v1.11.0
31M downloads/mo
#668 most downloaded on Packagist
dg/bypass-finals
What this package is like to depend on
Last release 1 months ago
24 Jul 2026
Release timing varies
gaps range from 1 weeks to 1.4 years
Some releases are documented
notes for 8 of 22 stable releases
Nothing withdrawn
no release was ever pulled
9 years old
22 releases · first in 2017
3 releases in the last 12 months
see the full history below
Release timeline
22 releases · Sep 2017 to Jul 2026Releases
latest 22-
v1.11.024 Jul 2026Release notes
Open source →BypassFinals now understands modern PHP:
finaldisappears not only from classes and methods, but also from properties and property hooks introduced in PHP 8.4. Caching got safer and smarter, path matching finally behaves on Windows, and PHPUnit users can configure path masks straight fromphpunit.xml.💥PHP 8.2
- PHP 8.2 is now the minimum. Support for PHP 7.1–8.1 has been dropped. If you're stuck on an older PHP, stay on 1.10.x.
✨ New Features
finalis now removed from properties and property hooks (PHP 8.4+), not just from classes and methods. The rule is inverted:finalsurvives only before constants, where it's a genuine feature rather than a mockability barrier.- PHPUnit extension learned
allowPathsanddenyPaths– restrict which files get rewritten without touching a single line of PHP. Semicolon-separated masks, right there inphpunit.xml:<parameter name="allowPaths" value="*/src/*;*/lib/*"/> <parameter name="denyPaths" value="*/generated/*"/>
debugInfo()now shows the full picture – allowed and denied path rules plus the cache directory, so you can see at a glance why a file wasn't modified.
🐛 Bug Fixes
final readonly int $xno longer produces invalid code. With both bypasses enabled it used to emit a bareint $x; a property must keep at least one modifier, so the first removed one now becomespublic.- Path masks match case-insensitively on Windows, where
C:/Src/andc:/src/are the same directory – as they always should have been. - Cache files are written atomically via a temp file and
rename(), so a process killed mid-write can no longer leave a truncated file behind and poison every subsequent run. [#80] - Stale caches invalidate themselves. The cache key now includes the algorithm version and the PHP version, so upgrading PHP or BypassFinals no longer serves you code rewritten by the old rules.
-
v1.10.215 Jun 2026Nothing published for this version
-
v1.10.104 Jun 2026Release notes
Open source →✨ New Features
- bootstrap.php – activate BypassFinals at the earliest possible moment, before
vendor/autoload.phploads, so nothing slips through unmodified (#74, #58)
🐛 Bug Fixes
- Fixed
proc_open()when given a['file', ...]descriptor spec – the native wrapper no longer chokes on file-based descriptors (#43) - Fixed premature EOF:
stream_eof()now waits for an actual empty read before reporting end-of-stream, preventing truncated reads (#75, #50) - The cache directory is now created recursively, so deeply nested cache paths just work out of the box (#70, #66)
- Cleared the stat cache after the
is_dir()check instream_open(), fixing stale filesystem state on cache writes (#69, #67) - Fixed
debugInfo()output so bypass tokens are reported correctly (#68) NativeWrapper::stream_seek()now detects whether the underlying stream is actually seekable instead of blindly seeking (#63)- Final-token removal now preserves constant names, so identifiers that happen to look like the
finalkeyword survive untouched (#64) - Added a
T_READONLYconstant polyfill for PHP < 8.1, keeping older runtimes happy (51736af) - Consolidated all cache I/O into a single native stream-wrapper cycle, simplifying the read/write path and reducing wrapper churn (#71, #55)
- bootstrap.php – activate BypassFinals at the earliest possible moment, before
-
v1.9.016 Jan 2025Release notes
Open source →- Make PHPUnitExtension configurable (#59)
- added BypassFinals::debugInfo()
-
v1.8.002 Jul 2024Release notes
Open source →- BypassFinals: added allowPaths() & denyPath()
- PHPUnitExtension: denies path 'vendor/phpunit'
-
v1.7.017 May 2024 -
v1.6.019 Nov 2023Release notes
Open source →- added PHPUnitExtension
- NativeWrapper: implemented stream_set_option()
- MutatingWrapper has been separated from BypassFinals
-
v1.5.116 Sep 2023 -
v1.5.023 Aug 2023 -
v1.4.113 Sep 2022Nothing published for this version
-
v1.4.013 Sep 2022Nothing published for this version
-
v1.3.109 Apr 2021Nothing published for this version
-
v1.3.015 Oct 2020Nothing published for this version
-
v1.2.215 Sep 2020Nothing published for this version
-
v1.2.114 May 2020Nothing published for this version
-
v1.2.008 May 2020Nothing published for this version
-
v1.1.308 May 2020Nothing published for this version
-
v1.1.203 Jun 2019Nothing published for this version
-
v1.1.115 Jan 2019Nothing published for this version
-
v1.1.020 Jul 2018Nothing published for this version
-
v1.0.107 Jun 2018Nothing published for this version
-
v1.013 Sep 2017Nothing published for this version