Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP readline() when STDIN other than keyboard

I'm writing an script that is able to read from stdin and then request for confirmation.

<?php
$stream = fopen('php://stdin', 'r');
$input = fgets($stream, 1024);
$confirmation = readline('Are you sure?');
if ( $confirmation == 'y' )
    /* Do dangerous stuff */

When I run it directly:

$ php script.php
inputdata
^D
Are you sure?

But I'm trying to run it using a file as STDIN. In that case, readline() returns false and no confirmation is prompted.

$ php script.php < data.txt

or

$ echo "foobar" | php script.php

How can I read both from the STDIN and keyboard when invoking this script in this way?

Thanks.

like image 849
superruzafa Avatar asked Jan 17 '23 08:01

superruzafa


2 Answers

Use fgetc function with STDIN. See example bellow.

$input = fgets(STDIN, 1024);
echo "\nAre you sure?\n";
$conf = fgetc(STDIN);
if($conf=='y'){
        echo "Great! Lets go ahead\n";
}else{
        echo "Okay, May be next time\n";
}

Console output

Sample 1

    $ echo 'data
    > y
    > ' | php php_readline.php

    Are you sure? 
    Great! Lets go ahead

Sample 2

$ php php_readline.php 
Some data

Are you sure?
n
Okay, May be next time
like image 163
Shiplu Mokaddim Avatar answered Jan 20 '23 14:01

Shiplu Mokaddim


According to a commenter ont he PHP page ( http://php.net/manual/en/book.readline.php ):

When readline is enabled, php switches the terminal mode to accept line-buffered input. This means that the proper way to use the cli when you pipe to an interactive command is to explicitly specify that php is not using the terminal for input:

php somescript.php < /dev/null | less

I believe the point is to append | less. Not knowing the structure of your data, presumably something might need to be done within your script to handle the transition from data to confirmation.

One might add a mechanism to detect when terminal line-buffered input is enabled.

like image 39
horatio Avatar answered Jan 20 '23 16:01

horatio