chrismec
chrismec

Reputation: 103

PHP: Pass file into script as stdin

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

Answers (2)

Josef Kufner
Josef Kufner

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

chrismec
chrismec

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

Related Questions