diff --git a/src/Command.php b/src/Command.php index 4902469..a64b2f1 100644 --- a/src/Command.php +++ b/src/Command.php @@ -60,7 +60,7 @@ class Command public $locale; /** - * @var string to pipe to standard input + * @var null|string|resource to pipe to standard input */ protected $_stdIn; @@ -159,7 +159,7 @@ public function setCommand($command) } elseif (isset($command[2]) && $command[2]===':') { $position = 2; } else { - $position = false; + $position = false; } // Absolute path. If it's a relative path, let it slide. @@ -172,8 +172,10 @@ public function setCommand($command) } /** - * @param string $stdIn If set, the string will be piped to the command via standard input. + * @param string|resource $stdIn If set, the string will be piped to the command via standard input. * This enables the same functionality as piping on the command line. + * It can also be a resource like a file handle or a stream in which case its content will be piped + * into the command like an input redirection. * @return static for method chaining */ public function setStdIn($stdIn) { @@ -345,8 +347,13 @@ public function execute() if (is_resource($process)) { - if($this->_stdIn!==null) { - fwrite($pipes[0], $this->_stdIn); + if ($this->_stdIn!==null) { + if (is_resource($this->_stdIn) && + in_array(get_resource_type($this->_stdIn), array('file', 'stream'), true)) { + stream_copy_to_stream($this->_stdIn, $pipes[0]); + } else { + fwrite($pipes[0], $this->_stdIn); + } fclose($pipes[0]); } $this->_stdOut = stream_get_contents($pipes[1]); diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 8a160b2..ff2cf70 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -233,5 +233,18 @@ public function testCanRunCommandWithStandardInput() $this->assertTrue($command->getExecuted()); $this->assertEquals("^I", $command->getOutput()); } + public function testCanRunCommandWithStandardInputStream() + { + $tmpfile = tmpfile(); + fwrite($tmpfile, "\t"); + fseek($tmpfile, 0); + $command = new Command('/bin/cat'); + $command->addArg('-T'); + $command->setStdIn($tmpfile); + $this->assertTrue($command->execute()); + $this->assertTrue($command->getExecuted()); + $this->assertEquals("^I", $command->getOutput()); + fclose($tmpfile); + } }