Solved

# STDIN under Windows?

Posted on 2005-04-13
997 Views
I am trying to write a PHP shell script that works in windows and linux.

I am reading from STDIN but having problems with windows. I am executing the script using a bat file and it seems to ask for input; I can't really work out what it does with the input (I press CTRL C to continue).

Any suggestions?
0

LVL 3

Expert Comment

on windows you need to use \con

like this:

if (substr(PHP_OS, 0, 3) == "WIN") {
$tty = fOpen("\con", "rb"); } else { if (!($tty = fOpen("/dev/tty", "r"))) {
$tty = fOpen("php://stdin", "r"); } } 0 LVL 3 Expert Comment you can also have a look at the comments on readline in the php manual... http://www.php.net/manual/en/ref.readline.php 0 LVL 6 Expert Comment pressing CTRL C terminates your shell script, be sure your script have the possibility to do I/O for example to handle your inputs : <?php$stdin = fopen('php://stdin', 'r');
echo 'Login : ';
$mystr = fgets($stdin,100);
echo 'Your login is : '.$mystr; fclose($stdin);
?>
0

Author Comment

Andy, it appears that $fp = fopen("php://stdin","r"); should work on Windows (?) Alex, what should I use instead of CTRL C ? Ie, when i have finished entering input in the shell window, what should i press? 0 Author Comment Perhaps this is my problem, i am doing: while ($data_bit = fgets(STDIN, 1024)) {

}

code (STDIN is defined above as php://stdin

Generaly what I use this for is pipeing email like:

|user@domain.com > /path/to/file.php

but I want to be able to just test it on windows entering a source text of unknown length.
0

LVL 6

Expert Comment

in windows console mode simply use enter to validate your inputs
to test it 1) start cmd 2) use this syntax : php \path\to\your_script.php
0

LVL 6

Expert Comment

shouldn't it be
while ($data_bit = fgets($STDIN, 1024)) {
rather than
while ($data_bit = fgets(STDIN, 1024)) { since$STDIN is the ressource handle.
0

LVL 6

Expert Comment

or more something like :
<?php
$stdin = fopen('php://stdin', 'r');$data_bit = fgets($stdin,1024); /* your code */ fclose($stdin);
?>
0

LVL 6

Expert Comment

then you can scan through your $data_bit with while or while (!feof($stdin)) {
$data_bit = fgets($handle, 1024);
echo $data_bit; } perhaps$data_bit = fgets($handle, 1); instead of$data_bit = fgets($handle, 1024); 0 Author Comment As i understand it STDIN in PHP > 4.3 is a constant holding the handle, it is auto created. I have got a test of what I am doing: <?php if (version_compare(phpversion(),'4.3.0','<')) { define('STDIN', fopen("php://stdin","rb")); define('STDOUT', fopen("php://stdout","rb")); define('STDERR', fopen("php://stderr","rb")); register_shutdown_function( create_function('' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;') ); } echo 'Login : ';$mystr = fgets(STDIN,100);
echo 'Your login is : '.$mystr; echo 'Password : ';$mystr = fgets(STDIN,100);
echo 'Your Password is : '.$mystr; echo 'Address : '; while (!feof(STDIN)) {$mystr .= fgets(STDIN, 1024);
}
echo 'Address is : '.$mystr; The problem is i can't get multiple line to work, in that I can't end the multiple line input without doing CTRL C 0 LVL 6 Expert Comment if you want to handle the multilines you can try something like : while(($mystr = readline("")) != ".") {
$mystr .= ($PHP_OS == "WIN") ? "\r\n".$mystr : "\n".$mystr;
}
and end your lines with a . instead of enter
0

Author Comment

Ok, i will try that. I dosen't seem as neat as how it works on linux, when I pipe a file to the php script it knows when its got all the data for some reason. Is there no way to replicate that in windows?
0

LVL 6

Accepted Solution

I do not think it will be same as on Linux but see the script that joshua at neocodesoftware.com provided on http://fr3.php.net/readline
section multilines it is what you need.
0

LVL 6

Expert Comment

also do not forget that to use readline / read functions you will need to have libreadline installed.
0

Author Comment

I see. Thanks very much Alex - much appreciated.
0

LVL 6

Expert Comment

you are welcome :) to resume this in combination with above :
<?php
function multilineread () { //function from  http://fr3.php.net/readline
do {
$in = read(); # test exit if ($in == ".") return $read; # concat input (PHP_OS == "WINNT") ? ($read = $read . ($read ? "\r\n" : "") . $in) : ($read = $read . "\n" .$in);

} while ($inp != "."); return$read;
}
if (version_compare(phpversion(),'4.3.0','<')) {

define('STDIN', fopen("php://stdin","rb"));
define('STDOUT', fopen("php://stdout","rb"));
define('STDERR', fopen("php://stderr","rb"));

register_shutdown_function(
create_function('' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;')
);
}

echo 'Login : ';
$mystr = fgets(STDIN,100); echo 'Your login is : '.$mystr;
echo 'Password : ';
$mystr = fgets(STDIN,100); echo 'Your Password is : '.$mystr;

echo 'Address : ';
$myaddress = multilineread(); echo 'Address is : '.$myaddress;

?>
0

Author Comment

It seems that it is based on the idea of closing the stream after reading a line of it, and that is why it seems to work it seems.
What its doing is not really taking a multi line input but appending lots of single line inputs into one string.

This might work for debugging like I want, but is very different to the linux read all date piped in method.
0

LVL 6

Expert Comment

yeah I agree with you, it is not very confortable, but under MS-DOS you have to use a escaping caracter of your choice for multilines, welcome to the world of MS-DOS :)
0

## Join & Write a Comment Already a member? Login.

### Suggested Solutions

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to count occurrences of each item in an array.

#### 754 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

#### Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!