php5 cli: no output - php

i've got a php script that runs on the command line. To improve it's performance, i would like to completely suppress it's output.
How can I do that?
Thanks!

Not sure about performance but you can use
php -q myscript.php > /dev/null

One way would be to call ob_start() to turn on output buffering, and periodically call ob_clean() if you really don't want the output (or use a dummy ob_start() callback which does nothing).
Not sure how much of a performance gain this would be, as internally, PHP is still processing the output, except it goes into a buffer rather than to stdout.
If you've got a lot of diagnostic output you want to prevent, than it might be more effective to refactor your code to allow that to be suppressed by an application option.

fclose(STDOUT);
This will work cross platform as the first line in the PHP script.

Using > /dev/null is not enough?

If you have access to the script replace all echo with //echo. Perfect performance increase, but you will need to check multi-line echo statements.

function ob_esity($b) { return ''; }
ob_start('ob_esity');

Related

PHP's exec() printing output -- doesn't seem to follow specs

One of my users is experiencing odd behavior that doesn't seem to follow the PHP exec() specs.
I'm invoking like so:
exec($cmd, $out, $ret);
I would expect this not to generate any output, but the user is seeing an error stack trace from $cmd printed when it errors out. Nothing in my code outputs anything, so it has to be coming out of exec(), but how? Am I misinterpreting the documentation?
I expect I could trap this inside of an output buffer then dispose of it, but I would rather prevent it... And whatever I do, I want to understand why this is happening first.
NOTE: I'm working on getting more specifics on PHP version and other d etails from the users, but do not have that information at this time. All I can say is that it is >= 5.2.4.
What you experience is the normal unix behaviour:
An executed command always has two output pipes: standard out and error out. The documentation states that all output is given back. That does not include stuff written to the error output. That is using a separate pipe py purpose to separate error and normal output. If you want to capture that too you have to change the command you execute, typically you map the error output to the standard output by appending a 2>&1.

Output Buffering? Why not?

I found few articles on the Internet that are suggesting use of ob_ functions, all of these emphase benefits, and there are no downsides of using functions mentioned.
My question is what are the downsides of using ob_ functions, or setting ini_set('output_buffering', '1'); ?
The cons of using output buffering entirely depend on the context of your usage.
One of the biggest cons of output buffering is your runtime error messages or warnings may get suppressed, and you may sometimes end up with erroneous data.
Consider this example:
<?php
function render_template() {
ob_start();
// Do some processing
fetch_template_and_render();
do_render();
// end capture
$output = ob_get_clean();
return $output;
}
memchace::set( $some_key, render_template() );
?>
If either of fetch_template_and_render or do_render throw run time errors, they will get dumped into your output, and eventually in this example will end up in the database or cache.
Here are 2 snippets that demonstrate what I mean which you can try for yourself
#1
<?php
echo 1/0;
?>
outputs
Warning: Division by zero on line 1
#2
<?php
ob_start();
echo 1/0;
$var = ob_get_clean();
?>
outputs nothing.
To avoid such cases, you will need to be diligent about error checking and take precautions.
When used diligently, ob_* functions are very powerful and super useful.
There are no major drawbacks, with proper implementation, to the use of output buffering.
Output buffering can allow errors/warnings/notices (except stop errors) to appear in the output without being readily apparent. This is typically resolved with proper error checking, better configuration of the php environment and the implementation of a good error handler (such as one that converts errors to ErrorExceptions which can be caught with try/catch - see Whoops! as an example of an error handler using ErrorExceptions).
Memory can possibly be a drawback, but the output size is typically insignificant for most scripts. An exception to this may be when sending large amounts of data, such as using fpassthru to deliver file content. This can be resolved by turning off the output buffering (ob_end_clean or ob_end_flush) before writing this content to the output.
Memory consumption is the most important drawback. I've recently built a PHP script that outputs a large chunk of XML data of several megabytes. The framework this 'page' was part of used output buffering. With output buffering, you need a memory buffer large enough to contain all the data. In my case it wasn't and the script failed.
If you output the data directly to the client, you don't have this problem. This is escpecially important in cases like this and when throughputting files. In case of generating a 'normal' HTML page, you will likely not use up the whole buffer, although you still need a lot of memory if you have many simultaneous requests.
Without buffering, the data is gone and doesn't trouble your server anymore. As long as the data is buffered, it can be changed or flushed, but actually puts a load on your server.
Here's a pretty good use for ob_ functions:
ob_start("ob_gzhandler");
Provided that the zlib extension is enabled in PHP, that should ensure your output is gz-compressed. It noticably speeds up page transfers for large pages.

Include -- using a string rather than a filename

I'd like to run include on a string rather than a file, but an unaware of how to achieve this.
//This is the desired functionality
include($filename);
//But I want to do something like this instead.
$file_contents = getFileFromCacheOrSomewhereElse($filename);
include($file_contents); // Doens't work...
eval($file_contents); // Also incorrect.
Please note: "eval" is not the same as include -- "include" echos out the contents of the file (and executes any PHP tags) while "eval" executes the string as PHP code.
An example use case is loading a template file from Memcache (as a string), then running include on that string, rather than running include and relying on PHP filecache.
If you can turn on the allow_url_fopen and allow_url_include php.ini settings, then an alternative is the data stream wrapper (manual).
include 'data:text/plain,' . urlencode($file_contents);
eval("?>" . $file_contents . "<?php ");
does it.
Storing PHP code in the memcache is not the best idea.
And evaling it thereafter is even worse.
Any opcode cache, APC or EAccelerator will cache your PHP files on the fly, with no strange efforts like this, and even parse it for the faster execution.
EDIT. Given the voting results after all these years, I assume that this question is attracting only noobs, who have the same strange whim. So I have to repeat: although it defeats your brilliant idea,
just leave your includes as is
They will be cached much better and executed much faster by the internal PHP's opcode cache.

How do I pipe rake output using php?

I'm building a RAKEFILE and I want to display the output on a php generated page as it gets executed.
I tried using system() since the PHP docs mention this:
The system() call also tries to automatically flush the web server's output buffer after each line of output if PHP is running as a server module.
This seems to work with multiple shell comands but when I execute rake I only get the first line:
(in /Users/path/to/proj)
Any ideas?
Cheers!
Try use exec() function
exec($command, $output);
$output is an array
//retrieved data
for($out = '',$x = 0,$len = count($output); $x < $len; $x++) {
$out .= $output[$x] . "\r\n";
}
or simple:
$out = join("\r\n", $output);
The system() call also tries to automatically flush the web server's output buffer after > each line of output if PHP is running as a server module.
This means you would only get the last line of output from the return value. The example in the system() manual page shows that and it suggests to use passthru() to get raw output. I usually use exec() though.
Turs out both functions system() & exec() actually work. The generated rake output when using --verbose isn't taken into consideration though. That's why I was confused. If anyone has more extensive knowledge on the distinction, do share :)

PHP + Python - use PHP to pass string to Python program, and parse output

I have a great Python program on my webserver, which I want to use from inside my PHP web app.
Here's an example of the python command, and output as you would see it in terminal:
>>> print MBSP.parse('I ate pizza with a fork.')
I/PRP/I-NP/O/NP-SBJ-1/O/i
ate/VBD/I-VP/O/VP-1/A1/eat
pizza/NN/I-NP/O/NP-OBJ-1/O/pizza
with/IN/I-PP/B-PNP/O/P1/with
a/DT/I-NP/I-PNP/O/P1/a
fork/NN/I-NP/I-PNP/O/P1/fork ././O/O/O/O/.
You might recognize this as a typical POS tagger.
In any case, I'm confused about how to use a PHP-based web app to send this program a string like "I ate pizza with a fork", and somehow get the response back in a way that can be further parsed in PHP.
The idea is to use PHP to pass this text to the Python program, and then grab the response to be parsed by PHP by selecting certain types of words.
It seems like in PHP the usual suspects are popen() and proc_open(), but popen() is only for sending, or receiving information - not both? Is popen() able to give me access to this output (above) that I'm getting from the Python program? Or is there a better method? What about curl?
Here are all my options in terms of functions in PHP:
http://us.php.net/manual/en/function.proc-open.php
I'm lost on this, so thanks for your wise words of wisdom!
I use exec() for this purpose.
exec($command, $output);
print_r($output);
If you want to get a little heavier / fancier... give your python script an http (or xmlrpc) front end, and call that with a GET/POST. Might not be worth all that machinery though!
You could use popen(), and pass the input to your Python script as a command line argument, then read the output from the file descriptor popen gives you, or proc_open() if you want to interact bi-directionally with the Python script.
Example 1 in the proc_open manual: http://us.php.net/manual/en/function.proc-open.php gives an example of this.
If your Python needs it as stdin, you could try popening a command line:
echo "I ate pizza!"|my_python_progam.py
and just read the output. As usual, do proper input validation before sending it to the command-line.
Something like this would work
$command = '/usr/bin/python2.7 /home/a4337/Desktop/script.py'
$pid = popen('$command',r)
........
........
.........
pclose($pid)

Categories