Reputation: 103
I am attempting to write some tests for an email parser I am building and having trouble getting started.
For normal operation an email will be piped to the script, but for the tests I want to simulate the piping action : )
My test is starting out like this:
#!/opt/php70/bin/php
<?php
define('INC_ROOT', dirname(__DIR__));
$script = INC_ROOT . '/app/email_parser.php';
//$email = file_get_contents(INC_ROOT . '/tests/test_emails/test.email');
$email = INC_ROOT . '/tests/test_emails/test.email';
passthru("{$script}<<<{$email}");
With the script as is, the only thing passed to stdin is the path to the test email. When using file_get_contents I get:
sh: -c: line 0: syntax error near unexpected token '('
sh: -c: line 0: /myscriptpath/app/email_parser.php<<<TestEmailContents
Where TestEmailContents is the contents of the raw email file. I feel like I have executed scripts in this manner in the past using the heredoc operator to pass data into stdin. But for the last few days I have been unable to find any information to get me past this stumbling block. Any advice will be mucho appreciado!
Upvotes: 0
Views: 618
Reputation: 2989
To read stdin in PHP you can use php://stdin
filename: $content = file_get_contents('php://stdin');
or $f = fopen('php://stdin', 'r');
.
To pass a string to an invoked process you have two options: popen
or proc_open
. The popen
function is easier to use, but it has limited use. The proc_open
is a bit more complicated, but gives you much finer control of stdio redirection.
Both function give you file handle(s) on which you can use fwrite
and fread
. In your case the popen should be good enough (simplified):
$f = popen('./script.php', 'w');
fwrite($f, file_get_contents('test.email'));
pclose($f);
Upvotes: 0
Reputation: 103
The syntax error experienced was exactly that. To get the file contents and pass it in as a here string I needed to single quote the string:
$email = file_get_contents(INC_ROOT . '/tests/test_emails/test.email');
passthru("{$script} <<< '{$email}'");
But, in my case passing in a raw email did not require the use of a here string. The line endings are preserved either way. Redirecting the file to the script yielded the same results.
$email = INC_ROOT . '/tests/test_emails/test.email';
passthru("{$script} < {$email}");
Upvotes: 1