1

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).

Damien Overeem
  • 4,487
  • 4
  • 36
  • 55
  • 2
    Sorry, you get this wrong: you cannot write to stdin by writing to stdout. The stream accepting the users input and forwarding it to your script cannot get fed by an echo from your script. That is simply impossible. This has nothing to do with the line break. it is more like trying to fuel a car by using a tube to connect the exhaust pipe to the gaz nozzle... – arkascha Apr 29 '14 at 09:47
  • I never said I wanted to do that. You misunderstood me. Basically I want to leave the "pointer" at the end of the question when i ask for input. After input is given, I want to either print the given input, or the default input. I simply want to print it behind the question, instead of under it. – Damien Overeem Apr 29 '14 at 09:49
  • possible duplicate of [How do I echo in PHP without carriage returns?](http://stackoverflow.com/questions/13754391/how-do-i-echo-in-php-without-carriage-returns) – niklasfi Apr 29 '14 at 09:53
  • That question does not provide any answers to the question. The accepted answer states "There was something wrong with the config". Other answers focus on the opening and closing of php tags, which also does not apply, since my whole file is php. – Damien Overeem Apr 29 '14 at 10:02
  • for us windows users this question may be useful: **[7105433/windows-batch-echo-without-new-line](http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line)**. – Ryan Vincent Apr 29 '14 at 11:04

1 Answers1

2

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).

Alma Do
  • 37,009
  • 9
  • 76
  • 105
  • Hi @AlmaDo :) Long time no see. And thank you for the clear answer. Never though about the enter indeed being processed simple because it is indeed pressed. Your solution will unfortunately not work, since I am indeed in a windows environment, but my question has been answered. Thanks again! – Damien Overeem Apr 29 '14 at 11:06
  • @DamienOvereem May be cygwin? good to see you too. So return to our php room :p and we'll see often – Alma Do Apr 29 '14 at 11:09