I have a php page that when called from a browser displays a page, it also generates a static html page so - http://somewebsite/create.php when run from a browser creates newpage.html.
I also run this page from the CLI #php create.php it creates newpage.html but I get all the output on the screen, this slows down execution and if I have to run it many times can take hours.
Is there a way to run #php create.php and to supress all output to the screen
MArtyn
Check out Output Buffering
You begin with ob_start() to start buffering output, then you can use $output = ob_get_clean() to get everything that would have been displayed and store it in $output, so you can do whatever you want with it.
I believe there are $_SERVER variables you can use to check if you're running from the command line or not. (Obviously you can check for the HTTP headers that are normally there, they will not be set from the CLI)
var_dump($_SERVER) and see if there's anything intuitive looking :)
You can pipe the output on the command-line to /dev/null such as:
php http://somewebsite/create.php > /dev/null
This doesn't actually stop output from being produced by php, only from being displayed.
If you actually want to stop the output from being produced, you could use php's output buffering with ob_start() and put the output into a variable with ob_get_flush() at the end of the code and only echo the output if a certain param is/is not passed to the script.
Related
I have a PHP file with the following contents:
1. <?php
2. $string = 'Hello world!';
3. echo $string;
4. ?>
I put a break on line 2 and line 4. I run the debugger. The browser output opens, the script has halted on line 2, and the browser output is empty. Makes sense! Then I jump to the next breakpoint at line 4, after the echo command. AT THIS POINT, should the browser update and display 'Hello world'? Or do debuggers not update the browser output step-by-step, and thus are NOT useful for browser display and are only useful for inspecting the inner-code itself?
Thank you!
The answer is a bit complicated here. In general, Xdebug will not stop output to the browser, and PHP will not do so either unless you have output buffering or automatic compression turned on.
However, the web server might buffer data up to a certain point before it sends it onwards to the browser. You can force the web server to flush its buffers by calling flush(): http://php.net/flush. Be aware though that some browsers, also wait until they have had enough data to actually show anything.
I have a script that shows a result done then i call an include file to run at intervals. I would like the script result to display on browser then include file will run in the back. Right now my browser is connecting but showing nothing.I would like the browser echo Done and Logging.
<?php
ob_implicit_flush(true);
require_once('syslog.php');
$syslog = new Syslog();
$line="My msg";
$hostname = gethostname();
$ip= #$REMOTE_ADDR;
$hostnameip = GetHostByName($ip);
$syslog->Send('127.0.9.1', $hostname." ".$hostnameip." ".$line);
echo"Done";
echo "Logging......";
ob_end_flush();
include('execute.php');
?>
I believe you'll be able to get what you want by calling the flush() method right after your echo commands.
The flush() function is described as -
Flushes the write buffers of PHP and whatever backend PHP is using (CGI, a web server, etc). This attempts to push current output all the way to the browser with a few caveats.
There are some special considerations when using this function. Certain apache modules and client side buffering will still be enforced, but for now however, I do believe this will help.
Try flush() before include after last echo.
I am running a script every night and the output of the script will only be send to a mail address. But the problem is that I need to receive a copy of the output in my own mailbox. I registered an shutdown handler in the script and I tried to send a mail with functions like ob_get_contents which actually shows data. But only the last thing I printed to the terminal.
cronMail('Cron', ob_get_contents());
The function called is just a simple function which adds the default receiver and sender and call the PHP Mail function.
The output in the mail is:
array()
While the terminal has te following output:
Starting cron...
Exiting...
array()
Can anyone tell me how to receive the whole output? I started the output buffer by using the ob_start method. And after each line I make sure there is an ob_flush method called so the output will also be send to the browser if the script is called directly.
ob_flush stands in your way, see the linked description on the manual page, it is pretty clear about that: It flushes the buffer so outputs it.
You do not want that. Remove the calls to it and you should be fine.
ob_start();
... your script without "ob_flush()" ...
$buffer = ob_get_clean(); # finally get the output buffer as string
echo $buffer; # pass output along for cron
cronMail('Cron', $buffer); # send your mail
This variant ensures that you get your own email but also the output is passed along to cron. This can be useful if you do some error reporting in the cronMail function, so that at least there is some way to further debug that.
Another alternative is to register an output handling function that stores the output on the go. But that is less trivial so I keep it out.
Final update
Seems like I did make a very simple error. Since I already have a stream implementation I can just not start reading from the stream :D
I'm trying to achieve fire-and-forget like functionality in PHP.
From php.net
<?php
ignore_user_abort(true);
header("Content-Length: 4");
header("Connection: Close");
echo "abcd";
flush();
sleep(5);
echo "Text user should not see"; // because it should have terminated
?>
This works if I open the script with a browser. (shows "abcd").
But if I open it with file_get_contents or some stream library it will wait for ~5 seconds and show the second text as well.
I'm using PHP 5.2.11 / Apache 2.0
Update
I seems there is some confusion about what I'm trying to accomplish.
I don't want to hide output using output buffers (that's stupid). I want to have the client terminate before the server starts a possibly lengthy process (sleep(5)) and I don't want the client to wait for it (this is what fire-and-forget means, sort off).
The use of output buffers is merely a side effect. I've amended the sample code without the use of output buffers.
What I don't understand is: why does this script behave differently when accessing it from the browser vs. fetching it in PHP with file_get_contents("http://dev/test.php") or some stream library? What I've seen in testing is that for instance stream_get_contents will actually block for 5 seconds before it returns any output at all, the is quite the opposite of what I want.
Update2
Some more results:
The browser somehow responds to the flush(). I can't figure out how to replicate this behavior with streams in PHP, my streams keep blocking.
I've tried fread and found that it behaves similar to stream_get_contents.
Specifying a maxlength has no effect, it will still block for ~5 seconds.
Changing the blocking mode has no effect (other than generating a bunch more calls to stream_get_contents()). It will wait ~5 seconds before returning anything.
stream_set_read_buffer has no effect (tested on a PHP 5.3.5 sever)
The second portion of text is showing up because you're stopping output buffering with ob_end_flush() and ob_end_clean(). When that happens PHP outputs content as normal. Try something like the following:
<?php
ob_start(); // turn on output buffering
print "Text the user will see.";
ob_flush(); // send above output to the user and keep output buffering on
print "Text the user will never see";
ob_end_clean(); // empty the buffer and turn off output buffering. your script should end here.
?>
It's important for ob_end_clean() to appear at the end of the script. It empties the buffer and does not send its contents to the user, thus keeping everything after ob_flush() hidden.
How do you access the script using file_get_contents? How do you access it with your browser? If you access the script without "http://", of course it will never get executed. Use the same URL as in the browser.
Edit:
The browser will render the page even before the connection is closed. Even if you flush, I don't think the connection is closed. You can fire up Wireshark and check. stream_get_contents and file_get_contents will block until they have all the output. Even if you flushed, they can't be sure that there isn't more content. Since the content-length header didn't seem to make {file,stream}_get_contents return earlier, you probably need to implement your own buffering, ala. fopen, read, fclose.
Seems like I did make a very simple error. Since I already have a stream implementation I can just not start reading from the stream :D
I have a php file that is fired by a cronjob every minute.
When the php file is fired it updates the database, sleeps, etc
It is programmed like this:
$start = microtime(true);
set_time_limit(10);
for($i=0;$i<5;$i++)
{
updateDB();
time_sleep_until($start + $i + 1);
}
If this piece of code is run i don't see any changes happening in the database. Another thing i notices is when i echo something out i is printed when the loop is ended in one piece.
[edit] I tried using flush and ob_flush, but it still didn't print line for line[/edit]
What can i do to avoid these errors. The database needs to be updated.
Another thing i was wondering is what the best way is to log this kind of thing. Can i log the results to a log file.
The loop itself looks fine. If it isn't updating your database, the error must be in your updateDB() function.
As to the echo thing. The output of scripts is often buffered. To force PHP to print it right away, you can call either call flush() whenever you want the output flushed, or you can just call ob_implicit_flush() at the top of the script and it will flush automatically every time you print something.
Also, if you are calling the script via a browser, the browser itself may further buffer the response before showing it to you.
And as to the logging, the simplest way is to pick a file somewhere and just use file_put_contents() to print whatever you want logged. Note the FILE_APPEND flag for the third parameter.
Looks like you are running from command line, in this case you may want to write to stderr so that there is no buffering. $stderr = fopen('php://stderr', 'w');
In the case of logging, just open a file, write to it, and close it. (fopen, fwrite, fclose);