Frage

For a command line application I am trying to ask a simple question using the following code (example is not real life, code, but resembles the "real" version):

echo "Do you want to quit? [Y]/N";
$handle = fopen ( "php://stdin", "r" );
$input = trim(fgets($handle));

if ( empty($input) ) {
    $input = 'Y';
    echo "Y\n";
}

The result I want, is the following - When a user does -NOT- provide input:

Do you want to quit? [Y]/N: N    // User only hits enter, not 'N'..

What I get is:

Do you want to quit? [Y]/N:    // User only hits enter, not 'N'..
N

So the question is: How do I force echo 'Something'; to NOT print a newline after the echo.

Basically I need the equivalent of bash's echo -n '...' (does not print the trailing newline).

War es hilfreich?

Lösung

To understand why is it so - you need to understand that there are two things: STDIN and STDOUT that are involved into program. And - yes, php does not add new lines. With simple echo "foo"; you'll get exactly "foo", without new line.

But why are you seeing new line then? Simple: because you've pressed "it". That is: you've pressed "enter" key, terminal got it and printed it. Your program, of course, also got it, but at that moment the "key" is already printed.

What can you do? On that step: nothing. It's already done and that's it. You'll see it in your screen. However, yes, there is a trick that I can suggest. You can use stty to maintain behavior, when you can control the input and/or output. Combined with system() you'll get the idea.

Here we are with code:

function emulatePrintable()
{
        $result = '';
        while($c = trim(fgetc(STDIN)))
        {
                echo($c);
                $result.=$c;
        }
        return $result;
}
system('stty -echo');
echo("Do you want to quit? [Y]/N ");
$result = emulatePrintable();
if($result==='') 
{
        echo("You didn't type anything!");
}
echo "\n"; //<--- this is to delimit program's end of work
system('stty echo');

What's happening? You're doing this:

  • Suppress any input printing with stty -echo. This is the trick. You're suppressing only input display, not output display. That is why you'll be able to see echo() strings from PHP
  • Emulating output for printable characters. That is: you still want to show what user is typing (your Y or N) - but you want to skip new line. Simple emulatePrintable() will do the work (may be not the best name, but at least I've tried)
  • After you've got the input (it's interrupted with EOL, for example) - you can examine what is it. If it's an empty string, then you've caught it: user typed nothing.
  • Now, do not forget to enable input display with stty echo - otherwise.. well, you'll end with "non-working" terminal.

Benefit: with this you'll be able even to decide, to print character or not (for example, to restrict only Y and N for output).

So this is the solution for unix-based OS. In Win - best of luck to you. You may check this page for console modes & related stuff, but I'm not sure it will work (since have not tested).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top