Does die() do an ob_end_flush()? - php

I can't seem to find a good answer on this anywhere. If I am running output buffering, and a die() is fired, does that kick off an ob_end_flush() as well?

Yes it does. Any time the script ends gracefully, the buffers will be emptied. The only non-graceful endings are if it segmentation faults or if it's killed (signal 9 SIG_KILL). The only place that die() does a hard-kill of the process is if you call it inside of a register_shutdown_function (But the buffers are flushed before the shutdown function is called, so there's no issue there). See Connection Handling for some more information...

Yes.
However, you can make the output empty if you have
register_shutdown_function('ob_clean');
earlier in the code.
In some cases we did not want to output the ob on a die().
I write this here in case it could help anyone who wants to do the same.

Related

Is there a way to disable automatic flush of output buffer

Is there a way to disable automatic output buffer flush in PHP? I can always use ob_clean (or one of derivative functions) but that still leaves us with situations where code execution is interrupted. Proper error handler containing buffer clean will again deal with most of those. But what if for example script encounters the die / exit command during the execution? It will terminate the script and buffer content will still get auto flushed to client. The only way to be 100% sure seems to be disabling auto-flush completly. But I'm not sure how to achieve that (if possible at all).
Another solution, you can always implement your OWN buffer, and flush when you feel so ...
So your code should begin as:
$buffer='';
After this, when you plan to print() something, simply replace print() with $buffer.=
Once you decide to flush the buffer, you simply do:
print($buffer); $buffer='';
By doing so, you not only can 100% control your buffer, but also you might set additional headers during the execution of your script, which can come really handy in some cases ...

PHP - echo before exec()

Good day!
I am having some issues with getting the echo statement to output before the execution of the exec()
<?
if (isset($_POST['ipaddress'])) {
$escaped_command = escapeshellcmd($_POST['ipaddress']);
if(filter_var($escaped_command, FILTER_VALIDATE_IP)) {
echo "Gleaning ARP information, please wait..";
$command = exec('sudo /sbin/getarp.exp');
The echo statement is being outputted after the execution of the $command. The execution time can be anywhere from 15-30 seconds depending on how large the ARP table on the remote router is. Is there an order of operations that I am not aware of? It appears that all the statements within the if statement are executed in parallel and not by line by line as I had assumed.
I would rather not a solution be provided, but some documentational links that would lead me to finding a solution. I have searched what I could, but was not able to find a viable solution.
Any help would be appreciated.
Thanks.
This is happening because the script will run in its entirety before any result/output is sent to the browser.
In PHP there is a concept of "output buffering".
Whenever you output something (e.g. using echo, print, etc.) the text is thrown into a buffer. This buffer is only sent at certain times (at the end of the request, for instance, or when the buffer is full).
In order to empty the buffer (to "flush" it) you need to do it manually. The flush() function will do this. Sometimes you also need to call ob_flush() (this is if you have opened custom output buffers yourself). It is generally a good idea to just call both functions and be done with it:
echo 'Wait a few seconds...';
flush(); ob_flush();
sleep(3);
echo ' aaand we are done!';
See Output Buffering Control for more information on output buffering in PHP.
This is probably an issue with the output buffer. PHP buffers output and writes it to the browser in chunks. Try adding a call to ob_flush() between the echo and the exec(); this will force PHP to write the current contents of the buffer to the browser.
By default, php does not send any of the output until the php script is done running completely. There is a solution. However, I hear it is a little browser dependent. I would test it on different systems and browsers to see if it is working:
ob_implicit_flush (true)
Put that before any of your echo/print commands and that should allow anything printed to show right up on the browser.
A more universal approach would be to integrate your page with asynchronous javascript. A process commonly referred to as "AJAX". It is a little more difficult because it requires the use of many interacting scripts, some client-side and some server-side. However, AJAX is the defacto way to do thing like this on the web.

How to stop PHP code execution?

Is there a way to immediately stop PHP code execution?
I am aware of exit but it clearly states:
Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit is called.
So what I want to achieve is to stop the PHP code execution exactly when I call exit or whatever.
Any help?
Edit: After Jenson's answer
Trial 1:
function newExit() {
__halt_compiler();
}
echo "start";
newExit();
echo "you should not see this";
Shows Fatal error: __HALT_COMPILER() can only be used from the outermost scope in which was pretty expected.
Trial 2:
function newExit() {
include 'e.php';
}
echo "start";
newExit();
echo "you should not see this";
e.php just contains __halt_compiler();
This shows startyou should not see this
Edit: Why I want to do this?
I am working on an application that includes a proprietary library (required through virtual host config file to which I don't have access) that comes as encrypted code. Is a sort of monitoring library for security purpose. One of it's behaviours is that it registers some shutdown functions that log the instance status (it saves stats to a database)
What I want to do is to disable this logging for some specific conditions based on (remote IP)
Please see the following information from user Pekka 웃
According to the manual, destructors are executed even if the script gets terminated using die() or exit():
The destructor will be called even if script execution is stopped using exit(). Calling exit() in a destructor will prevent the remaining shutdown routines from executing.
According to this PHP: destructor vs register_shutdown_function, the destructor does not get executed when PHP's execution time limit is reached (Confirmed on Apache 2, PHP 5.2 on Windows 7).
The destructor also does not get executed when the script terminates because the memory limit was reached. (Just tested)
The destructor does get executed on fatal errors (Just tested) Update: The OP can't confirm this - there seem to be fatal errors where things are different
It does not get executed on parse errors (because the whole script won't be interpreted)
The destructor will certainly not be executed if the server process crashes or some other exception out of PHP's control occurs.
Referenced in this question
Are there any instances when the destructor in PHP is NOT called?
whats wrong with return ?
echo "you will see this";
return;
echo "you will not see this";
You can use __halt_compiler function which will Halt the compiler execution
http://www.php.net/manual/en/function.halt-compiler.php
You could try to kill the PHP process:
exec('kill -9 ' . getmypid());
Apart from the obvious die() and exit(), this also works:
<?php
echo "start";
__halt_compiler();
echo "you should not see this";
?>
I'm not sure you understand what "exit" states
Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit is called.
It's normal to do that, it must clear it's memmory of all the variables and functions you called before. Not doing this would mean your memmory would remain stuck and ocuppied in your RAM, and if this would happen several times you would need to reboot and flush your RAM in order to have any left.
or try
trigger_error('Die', E_ERROR);

Is the die() or exit() function needed in the end of a php script?

In a php script I have some test and after the script the html page.
When a test fail i call die("Test 1 failed");
If no test fail the php script reach the end ?> and then load the html code after the php script.
Is this a good procedure? Or I need to write die() or exit() before the end of php script?
No you don't have to write that and this is not best practice. If the script reaches the end without fatal errros it will exit.
If this means "testing" for you, you're wrong. Testing should be done using unit tests. For php there is phpunit. Give it a try, that's the proper way of testing your code.
Edit: As CompuChip says in a comment, the only useful use case for exit is when you're writing a php based shell script that should return an error code. See the parameter section of the documentation for the exit() function.
You should never be using die() or exit in your production PHP scripts except in very specific cases. Instead, re-work your code paths to simply show an error message to the user rather than exiting the script early.
No you don't need that, but when writing console PHP scripts, you might want to check with for example Bash if the script completed everything in the right way. That's when you use exit() or die()
Is the die() or exit() function needed in the end of a php script?
No, PHP will end the script itself. If the script is an included file (called from another file) then it will end script in the included file and then continue with any code in the original file after where you included (if there is any code).
So you put die() or exit() where ever you want or need it.
For testing, put it after each block of code you test. I use them in some parts of testing if I just want PHP to show me something then stop, such as print out an array to make sure it's being constructed correctly etc.
eg:
print_r($array);
exit();
For other code tests, I sometimes just echo "Section A worked", etc, such as within if/else. If I want to know if a particular part of code is working or if some criteria is being met or not (basically, it lets you trace where PHP itself is going within your code).
All that said, don't use die() or exit() in production code. You should use a more friendly and controlled messaging setup. For security reasons and visual, as you could potentially give them some info like "ERROR Failed to load SomethingSecret". Also it doesn't look pretty when you page only half loads and then puts out an on screen error message which likely means nothing to the end user.
Have a read through this:
PHP Error handling: die() Vs trigger_error() Vs throw Exception
No !
This is not recommanded to use it
Use trigger_error or error_log to log the tests in your error.log. Then check it.
No you don't have to use these functions at the end of the script, because it exists anyway at the end of the script.
No need to put a die or an exit at the end of the scipt.
But you may use exit to terminate your script with a specific exit code (by default it's 0).
E.g
$ php -r "/* does nothing */;"
$ echo $?
0
$ php -r "exit(123);"
$ echo $?
123
http://php.net/exit
From the documentation:
The link to the server will be closed as soon as the execution of the
script ends, unless it's closed earlier by explicitly calling
mysql_close().
https://secure.php.net/function.mysql-connect
Nope, you don't need to call die() or exit(0 if you have another code to run, like you HTML code

register_shutdown_function Or ignore_user_abort?

Hey i've seen people recommend each of them, One calimed register_shutdown_function to be better but without explination.
I'm talking about which is better to send a response back and still preform other tasks.
I Wondered what really is the better method and why.
EDIT:
In the register_shutdown_function documentation, someone published the following method:
<?php
function endOutput($endMessage){
ignore_user_abort(true);
set_time_limit(0);
header("Connection: close");
header("Content-Length: ".strlen($endMessage));
echo $endMessage;
echo str_repeat("\r\n", 10); // just to be sure
flush();
}
// Must be called before any output
endOutput("thank you for visiting, have a nice day');
sleep(100);
mail("you#yourmail.com", "ping", "im here");
?>
Could it be better then any of the functions i stated?
ignore_user_abort() tells PHP/Apache to not terminate execution when the user disconnects. register_shutdown_function simply allows you to do some cleanup while PHP is in the process of shutting down.
register_shut_down is only useful if you need to do some cleanup that PHP's normal shutdown routines wouldn't take care, e.g. removing a manually created lock file, flipping a bit in a DB record somewhere, etc...
In older versions of PHP (<4.1.0 under Apache), register_shutdown_function() would ensure that the connection was closed before your shutdown functions ran. This is no longer the case. The endOutput() function in your edit should indeed do what you want, provided you don't have any output buffers open. Though, it does set the script to be able to run forever if necessary, which could be annoying if it goes into an infinite loop (especially during debugging). You might want to change set_time_limit() to use a value that actually reflects how many seconds the script should take.
It's probably best to avoid register_shutdown_function() if you don't need it, since it has some other odd behavior (such as not being able to add a second layer of shutdown functions to run if the first shutdown function calls exit()).

Categories