PHP writing lots of text to STDERR - php

When writing a large chunk to STDOUT in PHP you can do this:
echo <<<END_OF_STUFF
lots and lots of text
over multiple lines
etc.etc
END_OF_STUFF;
(i.e. heredoc)
I have the need to do a similar thing but to STDERR. Is there another command like echo but uses STDERR instead?

For a simple solution - try this
file_put_contents('php://stderr', 'This text goes to STDERR',FILE_APPEND);
The FILE_APPEND parameter will append data and not overwrite it.
You could also write directly to the error stream using the fopen and fwrite functions.
More info can be found at - http://php.net/manual/en/features.commandline.io-streams.php

Yes, using php:// stream wrapper: http://php.net/manual/en/wrappers.php.php
$stuff = <<<END_OF_STUFF
lots and lots of text
over multiple lines
etc.etc
END_OF_STUFF;
$fh = fopen('php://stderr','a'); //both (a)ppending, and (w)riting will work
fwrite($fh,$stuff);
fclose($fh);

In the CLI SAPI, it can be as simple as passing a Heredoc string as an argument to fwrite() with the STDERR constant.
fwrite(STDERR, <<< EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD
);

Related

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!
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}");
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);

Script reading from STDIN

I have a php script that reads text files. I use fgetc() to get every character one by one. I open file to read from with fopen(),and then I use file descriptor returned from fopen() as a first argument to fgetc(). I tried to do the same thing with reading from STDIN. I wanted to run the script in a terminal, give it the whole text (that was in a text file before) and press enter. I thought that the script would read it and will run as if it read from a text file, but it doesn't work. It only works when a type every single character alone and press enter after it. Why is that? Is there a possibility to make the script behave the way I wanted? That I can give it the whole text to the terminal at once? Should I use different functions or something?
$inputFile = fopen($path, "w");
while(($char = fgetc($inputFile)) !== false){
dosomething();
}
What I'm trying to do is to replace $inputFile in fgetc()with STDIN.
See http://php.net/manual/en/features.commandline.io-streams.php, second comment
Note, without the stream_set_blocking() call, fgetcsv() hangs on STDIN, awaiting input from the user, which isn't useful as we're looking for a piped file. If it isn't here already, it isn't going to be.
<?php
stream_set_blocking(STDIN, 0);
$csv_ar = fgetcsv(STDIN);
I think it's the same for fgetc. After all it
string fgetc ( resource $handle ) Gets a character from the given file pointer.
Emphasis mine.
See http://php.net/manual/en/function.fgetc.php
...

Difference between file, file_get_contents, and fopen in PHP

I am new to PHP, and I am not quite sure: what is the difference between the file(), file_get_contents(), and fopen() functions, and when should I use one over the other?
The first two, file and file_get_contents are very similar. They both read an entire file, but file reads the file into an array, while file_get_contents reads it into a string. The array returned by file will be separated by newline, but each element will still have the terminating newline attached, so you will still need to watch out for that.
The fopen function does something entirely different—it opens a file descriptor, which functions as a stream to read or write the file. It is a much lower-level function, a simple wrapper around the C fopen function, and simply calling fopen won't do anything but open a stream.
Once you've open a handle to the file, you can use other functions like fread and fwrite to manipulate the data the handle refers to, and once you're done, you will need to close the stream by using fclose. These give you much finer control over the file you are reading, and if you need raw binary data, you may need to use them, but usually you can stick with the higher-level functions.
So, to recap:
file — Reads entire file contents into an array of lines.
file_get_contents — Reads entire file contents into a string.
fopen — Opens a file handle that can be manipulated with other library functions, but does no reading or writing itself.
file — Reads entire file into an array
file_get_contents — Reads entire file into a string
fopen — Opens file or URL

php system command with output and return code

I am looking for something in php that would given output (raw) of a system command in a variable along with the return code.
exec does this, but the output is in array and hence the data returned is not proper(as \n comes in new index).
system outputs the data in the output stream and not in a variable.
shell_exec does not give the return value but gives raw data.
Sounds like you're looking for output buffering:
ob_start();
system($command, $returnCode);
$output = ob_get_clean();
This should preserve all white-space characters at the end of each output line (exec as you wrote destroys these, so implode would not be an option).
Alternatively, you can open a process and aquire the pipes (standard output, STDOUT) and read the output out of these. But it's more complicated (but gives you more options). See proc_open.

Reading php scripts from php file

I have a file named "connection.php". I want to read the contents of this file to a string. I use fopen, and read functions for reading. But when I am reading I just got only last 2-3 lines on that file. That means no PHP scripts can read like echo, functions etc. How can I read the whole contents on that file?
<?php
$str = file_get_contents('connection.php');
var_dump($str);
?>
note that if 'connection.php' contains '<?php' at the beginning, and you try to output it to a browser, you likely won't see anything unless you perform a "View Source".
Quoting the manual page of fread :
fread() reads up to length bytes from
the file pointer referenced by handle
. Reading stops as soon as one of the
following conditions is met:
length bytes have been read
EOF (end of file) is reached
a packet becomes available (for network streams)
8192 bytes have been read (after opening userspace stream)
If you want to read a whole file, you'll need to use some kind of loop, to read data until you reach the end of the file.
Or, as an alternate (probably easier), you can use file_get_contents, which will get you the whole content of the file with only one function call.
Which means no need for fopen + multiple fread + fclose ;-)
Perhaps your browser is hiding the content because it starts with '<?php'. You can try View Source in your web browser, or echo the contents in the following way:
<?php
$contents = file_get_contents('connection.php');
echo "<pre>";
echo htmlentities($contents);
echo "</pre>";

Categories