Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bypass Finals Laravel Package

dg/bypass-finals

dg/bypass-finals is a PHP library that removes the final keyword at runtime so you can mock final classes and methods in tests. It works with PHPUnit and other mocking tools, making legacy or third-party code easier to test without changing source.

View on GitHub
Deep Wiki
Context7
v1.11.0

BypassFinals now understands modern PHP: final disappears 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 from phpunit.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

  • final is now removed from properties and property hooks (PHP 8.4+), not just from classes and methods. The rule is inverted: final survives only before constants, where it's a genuine feature rather than a mockability barrier.
  • PHPUnit extension learned allowPaths and denyPaths – restrict which files get rewritten without touching a single line of PHP. Semicolon-separated masks, right there in phpunit.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 $x no longer produces invalid code. With both bypasses enabled it used to emit a bare int $x; a property must keep at least one modifier, so the first removed one now becomes public.
  • Path masks match case-insensitively on Windows, where C:/Src/ and c:/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.1

✨ New Features

  • bootstrap.php – activate BypassFinals at the earliest possible moment, before vendor/autoload.php loads, 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 in stream_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 final keyword survive untouched (#64)
  • Added a T_READONLY constant 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)
v1.10.0

✨ New Features

  • bootstrap.php – activate BypassFinals at the earliest possible moment, before vendor/autoload.php loads, 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 in stream_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 final keyword survive untouched (#64)
  • Added a T_READONLY constant 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)
v1.9.0
  • Make PHPUnitExtension configurable (#59)
  • added BypassFinals::debugInfo()
v1.8.0
  • BypassFinals: added allowPaths() & denyPath()
  • PHPUnitExtension: denies path 'vendor/phpunit'
v1.7.0
  • add settings to cache hash [Closes #53]
  • fixed throwing errors in exists-check functions (#54) [Closes #52]
  • open_stream fail when $path is directory (#56)
v1.6.0
  • added PHPUnitExtension
  • NativeWrapper: implemented stream_set_option()
  • MutatingWrapper has been separated from BypassFinals
v1.5.1

DG\BypassFinals::enable(bypassReadOnly: false);

v1.5.0
  • removes keyword 'readonly' too [Closes #39]
v1.4.0
  • implemented cache
  • calls previous wrapper if one was set [Closes #9]
  • divided into classes BypassFinals & NativeWrapper
  • fixed some bugs
  • tested in PHP 8.2
v1.3.1

fixed some bugs #28, #25

v1.2.0
  • requires PHP 7.1
  • Add setWhitelist() method to allow controlling which files get replaced. (#7)
v1.1.0
  • a lot of fixes
  • respects final as non-keyword [Closes #4]
v1.0.0
  • initial release
  • requires PHP 5.6
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules