exit, exit(), exit(0), die(), die(0) - How to exit script - php

I believe that all of these (and even die() or die(0)) are identical. If they are not identical, which is preferred for exiting a script successfully? If they are identical, is there any preferred standard to indicate successful script completion? I tend to use exit;.
EDIT: All of the answers have "die() and exit() are identical" even though I say that in my question. I updated to the title to hopefully make it clearer that this is NOT my question. I want to clearly indicate success from a command line script.

These are all identical. I'm pretty sure die() is just a straight-up alias to exit(), but even if it isn't, it still acts identically.
When one of these functions is given a string argument, it prints out the string before terminating the process. When it encounters an integer under 255, that integer is considered the return code for the process, which gets passed back to the process which invoked the PHP script. This is particularly useful when writing command line applications (PHP isn't web-only!).
As far as the difference between exit, exit(), and exit(0), there really is none. There is definitely no difference between the first two because exit is technically a language construct, not a function, so it can be called with or without parentheses, just like echo. Returning a code of 0 means "this program ran successfully/without errors", and while I don't know what exactly happens when you don't pass an argument, PHP.net says that an argument-less exit indicates success, so I would bet it returns 0, though again PHP.net doesn't show a default for the argument.

As several people have mentioned, die() and exit() are exactly the same.
If you look at the PHP documentation, there are two options for arguments:
An numeric value. This is only useful if you are using PHP from the command line, as opposed to a web server. A value of zero indicates success. Nonzero indicates a failure condition occurred.
A string value. This will be displayed to the browser when the exit occurs.
Instead of die() or exit(), I recommend using exceptions and a custom top-level exception handler to manage failure conditions.
You have more flexibility that way to do things like automatic error logging. Also, if you're using PHP to implement a JSON API, this exception handler can hand back a valid, error-indicating JSON snippet instead.

I would say that in regards with a better semantics die($arg); should be used for an abnormal or unexpected termination, even when -of course- you still have caught it. And exit($arg); should be used for a normal (expected / controlled) end of a process, like in break; for a for or while or a switch structure but with a definitive end.
Nevertheless .. I personally often use a general if { } else { } structure to control different branches of huge processes or output buffering so not having to use "exit" ..
I also use die($arg) in simple error-catching semantics like in
$db = mysql_connect([$args]) or die ($error); ...

die(); is just a synonym for exit(); and is functionally identical.
The standard way is to use exit code zero to signify success, and anything else to denote an error condition.

die() is typically used to kill the script with an error output:
die("There was a fatal error");
where-as exit is typically used as a successful exit (At least in my coding)
The PHP Manual says that the functions are identical.

I will get downvoted to hell, but in some cases when hacking in CLI, we do not want the program to get killed, while not wanting to continue the full execution.
Here the goal is to avoid making api calls to a separate hand-point file. Say I have a nice play button in my interface, that execute system calls.
Example 1: The program get killed after the job , no datas returned. This is not wanted.
if ($_GET["play"] != ""){
// Some job
exit;
}
/* Huge amount of data*/
Example 2: The program still runs, feeding the whole data in the GET request. This is unnecessary on this case. This is slowing down the browser with all the data, that he has already.
if ($_GET["play"] != ""){
// Some job
}
/* Huge amount of data*/
Example 3: The program still runs, no data returned as expected, the play command had been executed, but the whole data set get parsed, this is unnecessary job, can slow down php/the machine.
/* Huge amount of data*/
if ($_GET["play"] != ""){
// Some job
}
Example 4: The program still runs, no data returned as expected, the play command had been executed, the whole data had not been parsed, php returned super quickly 200OK with an empty response, as expected. Everyone happy!
if ($_GET["play"] != ""){
// Some job
goto END;
}
/* Huge amount of data*/
END;
Yes! Using GOTO, sometimes is to be considered -as the best to do 🔨 -!
https://www.php.net/manual/en/control-structures.goto.php

die is exactly equivalent to exit.
From the manual:
If status is an integer, that value will be used as the exit status..
This is only useful if you have some sort of wrapper that does something based on the exit status. Unless you have a specific need to report an exit code to the outside world, just exit;.

Related

Why can't the php interpreter not parse unset call after &&? [duplicate]

I've just read the page on Expressions in the PHP docs, and right at the top it says:
The simplest yet most accurate way to define an expression is "anything that has a value".
That simple definition includes all functions and most language constructs, however there a few language constructs that explicitly state they do not return a value.
Here is a list of language constructs that do return a value:
empty
eval
include
include_once
isset
list
require
require_once
print
Here are the interesting few which do not return a value, and therefore are not expressions:
die
echo
exit
return
unset
__halt_compiler
I find die and exit of particular interest, because they can be used as expressions in PHP despite having no return values. The following lines of code all throw a syntax error, as expected:
echo 'Hi' or echo 'Bye';
if(echo('foo'))
return return(1);
$foo['bar'] = isset($foo['bar']) ? unset($foo['bar']) : 0;
if(unset($foo['bar']))
__halt_compiler() or die;
However the following PHP code is completely free of syntax errors:
print 'Hi' or print 'Bye'; // Makes sense, print returns a value
if(!die() and exit) // Wait what's happening here?
quit(die(exit(quit()))); // die and exit don't have return values (does quit?)
$x = true ? die/2 : 5*exit();
$y = pow(die,7);
isset($_GET['bar']) or die(); // This one is actually pretty commonly used.
function quit(){
return exit;
}
I've looked through the PHP docs and can't find any mention of this special treatment of die() and exit(). Do any PHP experts know if this is documented anywhere. Is this intended behaviour, and is the isset($_GET['bar']) or die(); pattern safe to use; could it suddenly break in a future version of PHP?
PHP does not detect errors except at run time when the code path is reached. Unlike many other languages, it does not list the errors when the page is "compiled" - so you'll only see errors as their respective lines of source code are executed.
In your example, the evaluation of the return value of exit or die is never done. PHP doesn't report an error because it never tried to evaluate the result in the first place, because the thread exited.
die and exit (they share the T_EXIT token) fall under the rules for expr_without_variable during the parsing phase, which is why PHP is happy to have them in an expression context without giving a syntax error.
Do any PHP experts know if this is documented anywhere.
There is no description of the special treatment in the PHP manual, however the first example on the exit manual page shows it being used as … or exit.
Is this intended behaviour, and is the isset($_GET['bar']) or die(); pattern safe to use; could it suddenly break in a future version of PHP?
Yes. Yes. Anything's possible, however unlikely.
A wild guess is that die and exit do return a value, however, it will never be returned since the execution is halted before it is returned.
This might have been implemented in order to add some "usefulness" to the die and exit functions.
die and exit return value, however that value have to be used by the program that has called the PHP script. This comment describes the behavior.

is there a way to eval a piece of php code where die() or exit() is present and return to main code if it is called?

I do not have control over the code I'm executing. This is a third party function, but not user-entered. These are things that are versioned so it is impractical that I poke there and change all die()'s into something more sane. Because a new version is coming from time to time and then I could paradoxically make the code even more insecure by trying mess with it poor error handling.
so let's say we have a function:
fuction myfunc() {
// lot's of complicated code
if (!is_file('myfile.txt') exit('file not found');
// and so on
}
What I'm trying to do is to somewhat run that piece of code and return to my main thread and then act accordingly with that error.
I've tried die() or eval() but this returns the whole script.
Bummer ?
A Hail Mary approach is to use runkit's runkit_function_redefine or function_override to redefine the functions die and exit to throw an Exception instead.
A potential problem is that the 3rd party can catch those exceptions and might not deal with them correctly. It's also very likely that you can't properly deal with the exception either.
You can use register_shutdown_function to run code after exit has been called. You are somewhat limited in what you can do at this point as some services have already been shut down (such as autoloading). I think you can still output content, not sure about sessions and other headers.
Another approach would be to run the code in a seperate php process (or http request), for instance by calling php through exec.
A more solid approach can be to add predicitions to your own code, ensuring the bad states are never reached when calling the 3rd party code. It is possible that not all preconditions can be met.
Ideally only code that is an entry point (like a router script) may exit. Using exit anywhere else is just shoddy programming really.
If you have not read Halcyon's answer, you should have a look at it first.
Since you mention eval(), I assume you have the code as a string. I will refer to both die() and exit() by just the latter, but things should be relevant for both.
You can try and replace occurrences of die() and exit() with something, and then eval. It's simple but that can be very messy.
One thing to look out for, IF you decide to do this, is that you may end up replacing occurrences which are not really 'code'. For example, echo "Let him exit()";.
Also, when you consider possible equivalent syntax, like exit (); , exit; or exit(1);, it gets much more unpleasant. You'll have to handle those with a regex.
But if you can safely assume that
those two signatures (die() and exit()) are the only ones you need to worry about; and
that strings (or other content) are not going to contain those 'phrases'
then you can use this approach.

Understanding PHP declare() and ticks

Today I was looking through the php manual and stumbled upon a control structure declare.
The declare construct is used to set execution directives for a block
of code
This is what declare is supposed to do. To be honest I didn't understood it. On reading again it found a new thing Ticks
A tick is an event that occurs for every N low-level tickable
statements executed by the parser within the declare block. The value
for N is specified using ticks=N within the declare block's directive
section.
I didn't understand it either. what does it mean by N low-level tickable statements If there had been a good sample code, then it would have been easy to understand. But none was found in the manual. I have found some on SO Q1, which actually increased my curiosity and confusion. So can anyone what is this for and where can we use this.
My actual confusion is with this statement (from the linked so post) you can declare a tick-function which checks each n executions of your script whether the connection is still alive or not. So when I register a tick function with tick = 20 on a php file and execute it, the file will be alive till 20 execution is complete(got this idea when it was wrongly considered as multithreaded). This is the idea i have got, I dont think its correct..
Or is it a simple replacement for while($x = 20)
[EDIT 1]
I have also seen the implementation of declare() another section of php manual Function arguments
[EDIT 2]
Also in Process Control
You use the declare() statement to specify the locations in your
program where callbacks are allowed to occur. This allows you to
minimize the overhead of handling asynchronous events
When PHP is executing your script, the execution can be seen as a lot of statements being executed. Most statements cause a Tick, though not necessarily all statements do so. (Manual says: Typically, condition expressions and argument expressions are not tickable.)
This block would normally cause 5 ticks, as you are executing 5 statements:
$a = 1;
$B = 2;
$a = 3;
$B = 4;
$a = 5;
And this block would normally cause 5 ticks, and one more tick as the end of the while loop also is counted as a statement/tick:
while ($i < 5)
$a++;
With the help of declare(ticks=N) and register_tick_function(), you can now execute code in between the statements/ticks. The register_tick_function specifies which function should be called when a tick event occurs. And the declare sets how many tick should pass, before a tick event occurs.
With declare(ticks=1) and register_tick_function('someFunction'); you will call someFunction() code in between every statement/tick.
If you use declare(ticks=3), then someFunction() will be executed on every third statement/tick.
Example:
function handler(){
echo "x";
}
register_tick_function("handler");
$i = 0;
declare(ticks = 4) {
while ($i < 9)
echo ++$i;
}
This script will output: 1234x5678x9
It's that simple.
Now what is meant in the linked question with "whether the connection is still alive", is not really interesting on itself and is not actually related to the above mentioned. It is just something you COULD do on every tick event. But you can also do something totally different. What is mentioned is simply that some scripts can take quite some time to execute and that during the execution, the client can disconnect. (Imagine closing the browser, while the script is still running.) PHP will by default continue to run the script, even if the client has disconnected. You can use the function connection_aborted() to detect if the client has disconnected. This is something you COULD also do without using ticks at all.
Now let's say for example that you want your script to stop running as soon as the client disconnects. Simply use ...
function killme() {
if (connection_aborted()) {
die();
}
}
register_tick_function('killme');
declare(ticks=1);
... and your script will call killme() after each statement of your code. killme() will check if the client is still connected and die() when it isn't.
In practice: Ignore the declare() directive. Unless you run into code that makes use of it — which is very rare — you can safely forget that it ever existed.
That being said, here's the details. The declare() directive is currently used for two completely unrelated things:
As declare(encoding=…), for declaring the encoding of a PHP file. (In this sense, it's comparable to a server-side version of <meta charset="…">.)
But don't use this. Under most circumstances, the script encoding doesn't matter. If by some chance it does, the PHP encoding should be set globally (hopefully to "UTF-8") by the zend.script_encoding configuration value. Setting it at the file level is confusing and unnecessary.
As declare(ticks=…), for defining the frequency at which tick functions are called. Tick functions are called periodically by the PHP interpreter, and are set up using register_tick_function.
While some of the comments on php.net suggest using it to implement timeouts on network accesses, that doesn't actually work as expected, as ticks are not fired while the interpreter is blocked in a native function call. It might have some applications in benchmarking, but outside of that it's basically useless. I'd avoid it.
The one usage not mentioned in this or the possible duplicate answer is catching signals.
If you have a CLI script and want to catch user signals (like SIGHUP or SIGTERM (CTRL+C)), you need declare(ticks... together with pcntl_signal https://secure.php.net/manual/en/function.pcntl-signal.php which allows you to catch those signals (same like trap in shell scripts)

Why if/else vs. or/exit in PHP?

Seeing the exit() PHP documentation got me thinking:
$filename = '/path/to/data-file';
$file = fopen($filename, 'r')
or exit("unable to open file ($filename)");
Couple questions:
What are common use cases besides opening files for using exit()?
Since not every function everyone ever writes ends in exit(), how do you know to use it in some contexts vs. others?
Are if/else and or/exit interchangeable?
In that context, the or in that statement is one of PHP's logical operators which when used like that, will execute the second statement if and only if the first one fails due to short circuit evaluation.
Since fopen returned false, the or exit statement gets executed since the first part failed.
To understand it better, here is a quick explanation of short-circuit evaluation.
$x = 5;
$y = 42;
if ($x == 5 or $y == 42) {
echo "x or y is true";
}
In the above code, the expression $y == 42 is never evaluated because there is no need since the first expression was true.
In that example, they are using the same logic for deciding whether or not to evaluate the statement that calls exit.
To address your questions:
I wouldn't use exit when opening a file failed unless the program was very specific. The better thing to do would be to log an error and then return the error to the caller so they can decide what to do.
When to use exit completely depends on the code you are writing.
Given the explanation about short-circuiting, yes they are interchangeable in that sense. Using or exit is just a bit shorter than using if/else.
Hope that helps.
CLI scripts, exit can take an integer parameter which is fed back to the console to indicate success or some form of error
I'm not inclined to use exit() or die() in application code, since exceptions are preferred. However, I personally think you might be overcomplicating things a little bit... it kills script execution, so use it when you need to kill a script. Truthfully I mostly only ever kill scripts mid-execution when debugging (one-off breakpoints) and that's not ideal either (again exceptions do a better job).
The use of or is mostly convenient. Here's an interesting point though...
Why does
$resource = mysql_connect() || die('dead')
not work?
The answer is that the = operator takes precedence over or so that the assignment is made first like so: ($resource = mysql_connect()) or die(). In this way its exactly like doing an if(!($resource = mysql_connnect())) { die() }
I tend to avoid using exit() at all as it's a really ugly way to handle errors from the user's perspective.
If you must use it, any non recoverable error would be a candidate. For example, database query or connection failures, or remote request failures.
if/else is equivalent to ...or whatever(). It's just a style thing, with the latter form being more succinct.
I would say you use exit in a situation where your code cannot continue if the function you were doing failed. For example reading a file that is needed.

What is the difference between echo('exit'); die; and die('exit');?

I have seen some code do this:
if(something){
echo 'exit from program';
die;
}
...more code
And others that just use die:
if(something) die('exit from program');
...more code
Is there any inherent difference in when it would end the program, should I be aware of the code that comes after it? etcetera
UPDATE
I am asking mainly, if it is a coding style, or if there is a real reason why some is coded one way versus another. I am not asking what the difference between exit and die is.
No, there is no difference; they will both write "exit" to STDOUT and terminate the program.
I would prefer the die("exit") method as it's less typing, easier to comment out and semantically clearer.
As far as "speed", why would you care which is faster? Do you need your program to die really quickly?
RE: Your update
... any inherent difference in when it would end the program ...
There is no difference, inherent or otherwise. They're identical. The second option, die('exit'), is a single statement, and so requires no braces when used with an if statement; this has nothing to do with the die and everything to do with blocks and flow control in C-style languages.
RE: Your comment/second update
Which way you die is a matter of personal preference. As I said, they are identical. I would choose the 2nd option for the reasons listed above: Shorter, clearer, cleaner, which amounts to "better" in my opinion.
The difference between exit and die is that exit allows you to return a non-zero status, while die returns 0. Neither function is "better", they serve different purposes.
no difference.
And why asking for speed difference since you're dieing.
There IS a difference guys. DIE() can be used with other failable functions whereas echoing would need to caught as an error or exception.
$query = mysql_query("SELECT * FROM tablename") OR DIE(mysql_error());
Gives you an immediate catch/die sequence.
For the specific example you posted they are equal, since the $status is a string, but as the manual says this may not always be the case:
If status is a string, this function
prints the status just before exiting.
If status is an integer, that value
will be used as the exit status and
not printed. Exit statuses should be
in the range 0 to 254, the exit status
255 is reserved by PHP and shall not
be used. The status 0 is used to
terminate the program successfully.
So if instead of 'exit from program' you wanted to output, say 42 you would really need to do:
echo 42; die();
The language constructs exit() and die() are equivalent, at least according to the PHP manual. I use exit() when that line should be reached and I want the script to stop at that point. Die() on the other hand is for situations that should not occur. That's just what feels most natural for me, you don't have to agree.
Mostly it's coding style. However, if you are outputting debug messages, echo then die is better:
echo "The frobnuticator blew up!";
die;
becomes
//echo "The frobnusticator blew up!";
die;
Of course, you'd most likely have
if ($debug) echo "The frobnusticator blew up!";
die;
Which is much easier on (my|the) eye than
die($debug?"The frobnusticator blew up!":"");
From php manual :
Note: This language construct is equivalent to die().
But still there are difference between die and exit :
Using die() you can post a string : die("An error occurred");
Same result with using exit()
<?php
echo("An error occurred <br>");
exit(0);
?>
OR if you are cli or unix shell :
Using PHP on the command line, die("An error occurred") simply prints "An error occurred" to STDOUT and terminates the program with a normal exit code of 0.
<?php
fwrite(STDERR, "An error occurred \n");
exit(0); //
?>

Categories