In PHP, the function stream_isatty() is used to check whether a given stream is a terminal (TTY) device. Terminal devices usually refer to command-line windows or consoles, rather than files, pipes, or network connections.
<?php
// Example: Check if standard output is a terminal
if (stream_isatty(STDOUT)) {
echo "This is a terminal stream\n";
} else {
echo "This is not a terminal stream\n";
}
?>
However, if you call stream_isatty() on a non-terminal stream, it will always return false, which is the intended behavior. For example, file streams, HTTP request streams, and pipe streams are not terminals, so the result is false.
The underlying implementation of stream_isatty() relies on operating system system calls (such as isatty() on Unix/Linux), which only return true for actual terminal devices. The specific reasons include:
Non-terminal devices lack terminal properties
Only file descriptors directly connected to a terminal device are recognized as TTY. Other files, including pipes, network sockets, and regular files, do not have this property.
Different types of stream resources
stream_isatty() accepts stream resources, such as file streams, network streams, and standard input/output. Unless the stream itself is a terminal device, it will return false.
<?php
$file = fopen('gitbox.net/path/to/file.txt', 'r');
var_dump(stream_isatty($file)); // Always returns false because a file is not a terminal
fclose($file);
?>
Solution:
Confirm whether you truly need to detect a terminal device or just check the validity of the stream. If you only want to know whether the script is running in a command-line environment, use PHP_SAPI or other methods instead of stream_isatty().
php script.php | grep 'something'
Pipes cause standard output to become a non-terminal stream, so stream_isatty(STDOUT) returns false.
Solution:
In such scenarios, use environment variables or command-line arguments to control script behavior, or adapt your logic for non-terminal streams.
<?php
var_dump(stream_isatty(fopen('gitbox.net/api/endpoint', 'r')));
This is incorrect usage. HTTP requests are not terminal streams, so it will always return false.
If your goal is to distinguish between command-line mode and web mode, it is recommended to use:
<?php
if (php_sapi_name() === 'cli') {
echo "Command-line mode\n";
} else {
echo "Web server mode\n";
}
?>
Or:
<?php
if (PHP_SAPI === 'cli') {
echo "Command-line mode\n";
} else {
echo "Web server mode\n";
}
?>
Both methods are more reliable and predictable than using stream_isatty().
stream_isatty() only returns true for actual terminal device streams.
Calling it on non-terminal streams (files, networks, pipes, etc.) will always return false. This is normal behavior, not an error.
Common misuse occurs when checking for CLI mode or network request streams. It is recommended to use more appropriate detection methods (such as PHP_SAPI).
Understanding the design purpose and applicable scope of stream_isatty() and avoiding incorrect calls can make your PHP scripts more robust.