wp-cli / php-cli-tools

A collection of tools to help with PHP command line utilities
MIT License
671 stars 117 forks source link

Update TTY checks #145

Closed skeltoac closed 3 years ago

skeltoac commented 3 years ago

The function stream_isatty() (PHP manual) is available since PHP 7.2.0/8.0.

Determines if stream stream refers to a valid terminal type device. This is a more portable version of posix_isatty(), since it works on Windows systems too.

This update also enables the use of an Output stream as an argument without triggering a warning, as in the folowing code.

define( 'STDOUT', fopen( 'php://output', 'w' ) );
var_dump(posix_isatty(STDOUT));
var_dump(stream_isatty(STDOUT));

=>

<b>Warning</b>:  posix_isatty(): could not use stream of type 'Output' in <b>/usr/local/var/www/wp-cli/php/boot-fpm.php</b> on line <b>22</b><br />
bool(false)
bool(false)

It is necessary to define STDOUT in this way while using the fpm-fcgi SAPI. This is useful when running lots of WP-CLI commands in a high-volume task scheduler where up to 95% of CPU time is wasted on the redundant work of loading PHP code. We found that php-fpm's opcode caching reduces resource usage significantly, idling hundreds of CPU cores that are otherwise occupied loading the same code over and over again.

The fpm-fcgi SAPI runs WP CLI through a modified boot script. A command line program passes commands via an FCGI client and returns results on standard streams. It is suitable for non-interactive commands. This work will also be contributed to the wp-cli project.

dan-m-joh commented 3 years ago

The function isTty() in Streams.php returns wrong information. If the output is to an TTY then it returns false and if the output is a pipe or file it returns true, it should be the other way around.

The function should look like this (in my opinion):

        static public function isTty() {
                if ( function_exists('stream_isatty') ) {
                          return stream_isatty(static::$out);
                } else {
                        return (function_exists('posix_isatty') && posix_isatty(static::$out));
                }
        }

The function in Shell.php is correct (as it is also called isPiped()).