• Status: Solved
• Priority: Medium
• Security: Public
• Views: 1160

# STDIN under Windows?

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
• 10
• 6
• 2
1 Solution

Commented:
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 Commented: 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 Commented: 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');
$mystr = fgets($stdin,100);
echo 'Your login is : '.$mystr; fclose($stdin);
?>
0

Author Commented:
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 Commented: 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

Commented:
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

Commented:
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

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

Commented:
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 Commented: 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 Commented: if you want to handle the multilines you can try something like : while(($mystr = readline("")) != ".") {
$mystr .= ($PHP_OS == "WIN") ? "\r\n".$mystr : "\n".$mystr;
}
0

Author Commented:
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

Commented:
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

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

Author Commented:
I see. Thanks very much Alex - much appreciated.
0

Commented:
you are welcome :) to resume this in combination with above :
<?php
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;')
);
}

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

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

?>
0

Author Commented:
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

Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.