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
