On Fri, Sep 18, 2026, at 04:19, Pratik Bhujel wrote:
> Hi Tim, hi internals,
> 
> Thank you for the detailed feedback. Your observations on namespace grouping, 
> instance handles, unbacked enums, and standard library conventions made 
> complete sense.
> 
> Instead of just replying in theory, I took the time over the past couple of 
> days to step back, study how other ecosystems handle terminal interfaces, and 
> rebuild the extension accordingly. Version 0.8.0 is now released with that 
> exact architecture.
> 
> To answer your question regarding the domain problem:
> 
> The primary issue is that PHP CLI currently lacks native primitives for 
> non-canonical raw terminal mode and single keypress reading. Modern 
> interactive CLI tools in userland (such as Laravel Prompts, Symfony Console, 
> and interactive tools) want to deliver rich experiences like searchable 
> selection menus, autocomplete, multi-choice checkboxes, spinners, and hidden 
> password prompts.
> 
> Today, userland libraries face two severe problems:
> 
> 1. On Linux and macOS, packages work around the missing primitives by 
> executing the external stty tool using proc_open or exec. However, inside 
> minimal Docker containers (such as Alpine or slim environments where stty is 
> absent) or environments where process execution functions are restricted, 
> interactive CLI tools fail completely.
> 
> 2. On Windows, stty does not exist. Windows uses the Win32 Console API. 
> Because PHP has lacked these primitives, interactive CLI packages on Windows 
> either crash or fall back to crude text prompts where the user must type 
> choices manually and hit Enter. Reading password input without displaying 
> characters on Windows even required distributing separate helper executables.
> 
> 3. When a script exits unexpectedly or an unhandled exception occurs while 
> the terminal is in raw mode, the user shell is left corrupted with disabled 
> echo and hidden cursor.
> 
> Looking at how other languages tackle this:
> 
> * Rust (termion and crossterm): Rust relies on RAII guards where entering raw 
> mode returns a handle whose destructor automatically restores canonical 
> cooked mode on drop or panic.
> * Go (golang.org/x/term): Provides low-level primitives in the extended 
> standard library (MakeRaw, Restore, GetSize, ReadPassword) on top of which 
> tools like Bubbletea are built.
> * Node.js: Integrates raw mode toggling and size queries directly onto TTY 
> streams via libuv.
> * Python: Provides termios on POSIX and msvcrt on Windows in the standard 
> library to guarantee cross-platform terminal parity.
> 
> Following your guidance, version 0.8.0 adopts the following design:
> 
> 1. Namespace grouping:
> All symbols are placed under the Io\Terminal namespace, avoiding top-level 
> name reservation and aligning with modern asynchronous and stream polling 
> conventions.
> 
> 2. Instance-based Terminal handle:
> Classes are no longer static wrappers. The Io\Terminal\Terminal class 
> encapsulates a stream descriptor, created via named constructors stdin(), 
> stdout(), stderr(), or by wrapping custom stream resources.
> 
> 3. Automatic RAII cleanup:
> Both Terminal instances and ModeToken objects track active raw mode and 
> automatically restore terminal state upon destruction. If an uncaught 
> exception terminates script execution, the destructor restores canonical mode 
> so the developer shell is never left broken.
> 
> 4. Unbacked enums:
> Backend, Stream, ColorDepth, and Key are now unbacked enums matching core 
> standards. Methods such as bits() on ColorDepth supply numerical details 
> without scalar backing.
> 
> 5. Free-standing procedural functions:
> Io\Terminal provides procedural functions like is_tty(), read_key(), and 
> get_size() for functional script usage.
> 
> 6. Compatibility:
> The legacy Terminal facade and class aliases remain in place so existing 
> userland code continues to work smoothly.
> 
> The complete codebase, 49 tests, and the continuous integration matrix 
> covering Unix and Windows across PHP versions 8.1 through 8.5 are live on 
> GitHub and installable via PIE (package prateekbhujel/php-terminal).
> 
> The GitHub repository is here:
> https://github.com/prateekbhujel/php-terminal
> 
> Release v0.8.0 with prebuilt Windows DLL assets:
> https://github.com/prateekbhujel/php-terminal/releases/tag/v0.8.0
> 
> I would love to hear any further thoughts on whether this design aligns with 
> what you would like to see for an RFC targeted at PHP 8.7.
> 
> Thanks,
> Pratik

Meta question: can you please use your email’s “reply” feature instead of 
writing a new email with the same subject each time. That allows people to 
follow the thread. 

— Rob

Reply via email to