|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2015-06-22 14:45 UTC] nerdbeere2k at gmail dot com
 Description:
------------
Explaining my whole setup for this would take some time so i'm gonna try to describe it as short as possible.
I have a java application where i send some string to php-cli via standard input and read a result string back from standard output to do something else with it.
I do this several times, so the php-cli process is getting several commands to work off, and i read the results back.
The issue/bug now is that for every fgets call i make the process hangs for 100ms.
This worked like a charm until version php-5.5.17 and broke in version php-5.5.18. php-5.6.* seems to have this issue as well.
The changelog didn't exactly point towards a change that might've led to this as far as i could see.
Especially weird is that it all works fine if i put a "usleep(1)" before the fgets call...
I wrote some example breaking down the problem to as few lines as possible:
<?php
while(!feof(STDIN)){
    // usleep(1) <- adding this seems to fix this behaviour...
	// THIS WILL BLOCK FOR 100ms for every fgets call
    $s = fgets(STDIN);
    fwrite(STDOUT, $s);
}
?>
This script is called from a java application like this (tested on jdk1.8.0_20):
public static void main(String[] args) {
	try {
		Process p = Runtime.getRuntime().exec("./php-5.5.18/php.exe -f ./php-5.5.18/test.php");
		InputStream inputStream = p.getInputStream();
		OutputStream outputStream = p.getOutputStream();
		byte[] buffer = new byte[1024];
		while(p.isAlive()){
			outputStream.write("TEST\r\n".getBytes());
			outputStream.flush();
			int read = inputStream.read(buffer);
			if(read > -1){
				System.out.println(new String(buffer, 0, read));
			}
		}
	} catch (IOException ex) {
		ex.printStackTrace();
	}
}
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 03:00:01 2025 UTC | 
Thanks for the report. I've modified your snippet to see the timings <?php while(!feof(STDIN)){ // usleep(1) <- adding this seems to fix this behaviour... // THIS WILL BLOCK FOR 100ms for every fgets call $t0 = microtime(1); $s = fgets(STDIN); $t1 = microtime(1); echo "fgets() took ", (($t1 - $t0)*1000), "ms\n"; fwrite(STDOUT, $s); } But i don't reproduce this. Call it like echo hello | php.exe -n bugs\69900.php on my machine, either PHP 5.5 or 7, the output is like fgets() took 0.015974044799805ms hello fgets() took 0.015974044799805ms Please provide a stable reproduce case for what you describe. Otherwise, the issue you experience is probably not fgets(). Thanks.Hello ab, first thank you very much for looking into this! i tried to simplify this more by removing the java part, and the issue seems to occur here too. I'd agree with you, its probably not a fgets problem but seems to be a general problem with the STDIN/STDOUT stream, but i can't point out what it could be as i am not familiar with the php internals. However, this is the php-only testcase i came up with where the problem occurs: <?php $descriptorspec = array(0 => array("pipe", "r"),1 => array("pipe", "w"), 2 => array("file", "error-output.txt", "a")); $pipes = array(); $process = proc_open(PHP_BINARY.' -f test.php', $descriptorspec, $pipes); if(is_resource($process)){ for($i = 0; $i < 10; $i++){ fwrite($pipes[0], "hello\r\n"); $t0 = microtime(1); $s = fgets($pipes[1]); $t1 = microtime(1); echo $s; echo "fgets() took ", (($t1 - $t0)*1000), "ms\n"; } fclose($pipes[0]); fclose($pipes[1]); proc_close($process); } else die("process creation failed!"); ?> and the test.php file: <?php while(!feof(STDIN)){ $s = fgets(STDIN); fwrite(STDOUT, $s); } ?> The output that php-5.5.26 generates when calling it is as follows: C:\tmp\php_bug_report_69900\>.\php-5.5.26\php.exe -f passproc.php hello fgets() took 100.00491142273ms hello fgets() took 100.00610351562ms hello fgets() took 100.00610351562ms hello fgets() took 100.00586509705ms hello fgets() took 100.00514984131ms hello fgets() took 100.00586509705ms hello fgets() took 100.00610351562ms hello fgets() took 100.00491142273ms hello fgets() took 100.00610351562ms hello fgets() took 100.00586509705ms The output with php-5.5.17 is as follows: C:\tmp\php_bug_report_69900\>.\php-5.5.17\php.exe -f passproc.php hello fgets() took 19.001007080078ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms hello fgets() took 0ms Hope this helps! Thanks again!By the way, if you call the process like this: $process = proc_open(PHP_BINARY.' <?php while(!feof(STDIN)){ $s = fgets(STDIN); fwrite(STDOUT, $s); } ?>', $descriptorspec, $pipes); The problem doesnt occur... just in case someone wonders why i used two separate files.