bypass-finals
bypass-finals copied to clipboard
Using is_file() with PHP 8.0
Hi, Is it possible that this package isn't ready for PHP 8.0 yet? I have problem using is_file() function. It executes url_stat(), which uses @$this->native(...), and when the file doesn't exist it throw some exception that is impossible to catch by try-catch block: "stat(): stat failed for 'filename'"
I've checked it again, and instead of @$this->native(), just put it into try-catch block and it will enough solution.

@dg Is it possible to fix it soon? Your package is really useful, but without these changes I cannot use it anymore. :(
That's strange that it doesn't work, because there is a test for that and it passes even in PHP 8.0
https://github.com/dg/bypass-finals/blob/7377e1f8143a75063049c589bd6fb24eeaf430d6/tests/BypassFinals/native.errors.phpt#L78
public function url_stat(string $path, int $flags)
{
$func = $flags & STREAM_URL_STAT_LINK ? 'lstat' : 'stat';
return $flags & STREAM_URL_STAT_QUIET
? @$this->native($func, $path)
: $this->native($func, $path);
}
@PierwszyTV, current implementation url_stat uses error control operator "@" and gets PHP_STREAM_URL_STAT_QUIET flag for is_file function (see https://github.com/php/php-src/blob/master/ext/standard/filestat.c#L793)
So exception can't be thrown Please provide more info for debug
Finally I found a way how to reproduce a bug. Try the following code:
(new SplFileInfo('filename'))->isFile()
Result: RuntimeException: stat(): stat failed for filename
SplFileInfo::isFile
can't throw an exception by guide (link)
@dg any thought how to resolve bug?
Please check https://github.com/dg/bypass-finals/pull/34/files
@dg This is indeed strange. With one liners on Windows with PHP 8.1.0
$ php -n -r 'require __DIR__ . "/vendor/autoload.php"; DG\BypassFinals::enable(); stat("filename");'
Warning: stat(): stat failed for filename in D:\Web\dev\bypass-finals\src\BypassFinals.php on line 247
Warning: stat(): stat failed for filename in Command line code on line 1
but
$ php -n -r 'require __DIR__ . "/vendor/autoload.php"; DG\BypassFinals::enable(); (new SplFileInfo("filename"))->isFile();'
Fatal error: Uncaught RuntimeException: stat(): stat failed for filename in D:\Web\dev\bypass-finals\src\BypassFinals.php:247
Stack trace:
#0 D:\Web\dev\bypass-finals\src\BypassFinals.php(247): stat('filename')
#1 D:\Web\dev\bypass-finals\src\BypassFinals.php(238): DG\BypassFinals->native('stat', 'filename')
#2 [internal function]: DG\BypassFinals->url_stat('filename', 6)
#3 Command line code(1): SplFileInfo->isFile()
#4 {main}
thrown in D:\Web\dev\bypass-finals\src\BypassFinals.php on line 247
Looks like an SPL throws an exception. Similar case described here: https://stackoverflow.com/questions/25296178/why-would-phps-stat-throw-a-runtimeexception
Didn't find any PHP bug.
@milo It normally changes the error handler 🤦♂️ (in spl_directory.c)
zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling);\
php_stat(intern->file_name, func_num, return_value); \
zend_restore_error_handling(&error_handling); \