Nested switch issue

Down another rabbit hole: this is a simple function to return console input while checking that it is vaguely what is expected for the field (alpha, integer, etc.) and of acceptable length. The control features in the outer switch statement work fine, but nothing happens when entering input. What am I missing? [PHP CLI 8.3.21 on xubuntu 24.04]

	function console(int $length, string $type) : string {
		$input = [];
		readline_callback_handler_install("", function() {});
		$keypress = NULL;
		while (is_null($keypress))	{
			$keypress = stream_get_contents(STDIN, 1);
			switch (ord($keypress))	{
				case 10 :					// return
					return join($input);
					break;
				case 27 :					// escape
					return "\e";
					break;
				case 127 :					// backspace
					array_pop($input);
					fwrite(STDOUT, chr(8) . chr(32) . chr(8));
					break;
				default :
					if (count($input) < $length)	{
						switch ($type)	{
							case "I" :							// integer
								if (in_array($keypress, range("0", "9")))	{
									$input[] = $keypress;
									fwrite(STDOUT, $keypress);
								}
								break;
							case "N" :							// number
								if (in_array($keypress, array_merge(range("0", "9"), [".", ",", "+", "-"])))	{
									$input[] = $keypress;
									fwrite(STDOUT, $keypress);
								}
								break;
							case "D" :							// date
								if (in_array($keypress, array_merge(range("0", "9"), ["-"])))	{
									$input[] = $keypress;
									fwrite(STDOUT, $keypress);
								}
								break;
							case "A" :							// alphanum
								$input[] = $keypress;
								fwrite(STDOUT, $keypress);
								break;
						}
					}
					break;
			}
			$keypress = NULL;
		}
	}
function console(int $length, string $type): string {
    $input = [];
    
    // Turn off canonical mode and echo
    system('stty -icanon -echo');
    
    while (true) {
        $keypress = fgetc(STDIN);
        
        if ($keypress === false) {
            continue;
        }
        
        switch (ord($keypress)) {
            case 10:                    // return
                system('stty icanon echo'); // Restore terminal settings
                echo "\n";
                return implode('', $input);
                
            case 27:                    // escape
                system('stty icanon echo'); // Restore terminal settings
                return "\e";
                
            case 127:                   // backspace
                if (!empty($input)) {
                    array_pop($input);
                    fwrite(STDOUT, "\x08 \x08");
                }
                break;
                
            default:
                if (count($input) < $length) {
                    switch ($type) {
                        case "I":                            // integer
                            if (ctype_digit($keypress)) {
                                $input[] = $keypress;
                                fwrite(STDOUT, $keypress);
                            }
                            break;
                        case "N":                            // number
                            if (preg_match('/^[0-9.,+-]$/', $keypress)) {
                                $input[] = $keypress;
                                fwrite(STDOUT, $keypress);
                            }
                            break;
                        case "D":                            // date
                            if (preg_match('/^[0-9-]$/', $keypress)) {
                                $input[] = $keypress;
                                fwrite(STDOUT, $keypress);
                            }
                            break;
                        case "A":                            // alphanum
                            $input[] = $keypress;
                            fwrite(STDOUT, $keypress);
                            break;
                    }
                }
                break;
        }
    }
}
echo "Enter a number (max 5 digits): ";
$result = console(5, "I");
echo "\nYou entered: $result\n";

Tks - I started out with preg_match but don’t trust my regex skills. :weary: I still don’t understand why my code didn’t work - or at least not after one or two times thru.

Edit: Something else is afoot here: I can’t get your code to work either. I’ll keep working on this and see what I can narrow down.

I was passing field spec (row, column, length, etc) data in an exploded array read from file; the last one - type - included the trailing \n which I neglected to trim.

Sponsor our Newsletter | Privacy Policy | Terms of Service