-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
Description
On Unix-like systems, closing a std file handle has the useful property that the next file handle you open will inherit its place. This provides a very simple and effective way to reroute stdin/stdout/stderr during run time.
This has historically also been possible through PHP-CLI scripts, and as a result has become common practice, oft-repeated boilerplate code for using pcntl_fork() in particular, where it is almost always desirable for the forked children to stop using the parent's stdin/stdout/stderr.
This used to be as simple as, for example:
<?php fclose(STDIN); fclose(STDOUT); fclose(STDERR); $in = fopen('/dev/null', 'r'); $out = fopen('stdout-now-goes-here.txt', 'a'); $err = fopen('stderr-now-goes-here.txt', 'a');
The fix for an unrelated issue in #8575, and unfortunately included in both PHP 8.1.7 and PHP 8.0.20, also makes it impossible for PHP code to willfully close the std file handles anymore. This breaks a whole swath of past code that depended on this functionality, a rather unwelcome and unexpected change for minor releases.
Here's a test:
--TEST-- std handles can be deliberately closed --SKIPIF-- if (php_sapi_name() != "cli") { die("skip CLI only"); } if (substr(PHP_OS, 0, 3) == 'WIN') { die("skip not for Windows"); } --FILE-- <?php fclose(STDERR); var_dump(@fopen('php://stderr', 'a')); ?> --EXPECT-- bool(false)
With PHP 8.1.7 or 8.0.20 this now results in the following output instead:
resource(5) of type (stream)
3v4l link: https://3v4l.org/OgYWN
PHP Version
PHP 8.1.7
Operating System
Linux, macOS