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

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
thepadders
Asked:
thepadders
  • 10
  • 6
  • 2
1 Solution
 
AndyWHVCommented:
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
 
AndyWHVCommented:
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
 
alextr2003frCommented:
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
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
thepaddersAuthor 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
 
thepaddersAuthor 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
 
alextr2003frCommented:
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
 
alextr2003frCommented:
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
 
alextr2003frCommented:
or more something like :
<?php
  $stdin = fopen('php://stdin', 'r');
  $data_bit = fgets($stdin,1024);
  /* your code */
  fclose($stdin);
?>
0
 
alextr2003frCommented:
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
 
thepaddersAuthor 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
 
alextr2003frCommented:
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
 
thepaddersAuthor 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
 
alextr2003frCommented:
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
 
alextr2003frCommented:
also do not forget that to use readline / read functions you will need to have libreadline installed.
0
 
thepaddersAuthor Commented:
I see. Thanks very much Alex - much appreciated.
0
 
alextr2003frCommented:
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
 
thepaddersAuthor 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
 
alextr2003frCommented:
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.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

  • 10
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now