Errors when calling exit() function for fastCGI? - php

I've been reading that people face problems when using the exit function in their php script while running fastCGI
https://serverfault.com/questions/84962/php-via-fastcgi-terminated-by-calling-exit
http://php.net/manual/en/function.exit.php
"It should be noted that if building a site that runs on FastCGI, calling exit will generate an error in the server's log file. This can quickly fill up."
However my error log isn't reporting this problem after running this simple script even though I have fastCGI configured:
<?php
$num=2;
if($num==2){
exit();
}
?>
Would it be safe to use the exit function while I have fastCGI configured? And are there any alternatives to the exit function in php?
EDIT: I'm using the exit() function form form validation (ie if a form is valid exit, if not parse all the posted variables into the text fields.)

There are a few legitimate reasons to use exit() which is the same as die(). One example would be to follow a header Location: redirect.
Form validation is not the place to use die(). Structure your code so that you utilize functions or classes with methods that return values instead, and utilize branching logic.
In terms of fastcgi, if exit is used appropriately for situations where code is reached that should not be, then those situations will be atypical and a few log messages should not be a problem. Having a log file fill up seems a pretty silly reason not to do something -- an active webserver is logging every request and nobody argues that you shouldn't have a web log.

There's a really nice alternative to exit() posted on the exit() man page by
"dexen dot devries at gmail dot com":
If you want to avoid calling exit() in FastCGI as per the comments
below, but really, positively want to exit cleanly from nested
function call or include, consider doing it the Python way:
define an exception named `SystemExit', throw it instead of calling
exit() and catch it in index.php with an empty handler to finish
script execution cleanly.
<?php
// file: index.php
class SystemExit extends Exception {}
try {
/* code code */
}
catch (SystemExit $e) { /* do nothing */ }
// end of file: index.php
// some deeply nested function or .php file
if (SOME_EXIT_CONDITION)
throw new SystemExit(); // instead of exit()
?>

Related

PHP - Should I add the die() function at the end of every php script? [duplicate]

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

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

Preventing crash in user-written includes()

Consider the following code:
try {
include_once "malformedFile.php";
} catch(Exception $e) {
return null;
}
I have no way to ensure that the file malformedFile.php is valid PHP code, won't crash or won't call die(). How can I continue onto the catch even if malformedFile.php dies or crashes? My interest is to make the application as robust as possible while still allowing users to implement their own plugins via includes.
Thanks.
Unfortunately, you cannot. If the included code causes a fatal error (e.g. bad syntax) you 're dead in the water.
What you could try is loading the file manually and then calling eval:
$code = file_get_contents("malformedFile.php");
eval($code);
Of course this is something you should think thrice before doing because as we all know eval is evil etc.
The most robust option would be to spawn another process that does the include for you (so if it dies unexpectedly no big deal), but communicating between the parent and child processes will be much harder than just having one process.
Include will include source, no way around it.
Maybe you can call this file as an external process and just use the results. This could be done like a CLI script or with a separate CURL call.

PHP how to trigger user error with trigger_error in an object destructor while the script shuts down?

While implementing some class I've run into a little problem:
If the script ends and destructors are called because the script has finished, I wanted to trigger an error occasionally.
I thought the trigger_error() function would be of use. However, if error_reporting(-1) the triggered error is not send any longer to STDOUT or STDERR - while it is expected to do so (e.g. if not within the __destructor/termination phase of the script, trigger_error works as expected).
If I echo some message out, it will be send to STDOUT (CLI mode).
I now wonder
how I can trigger an error in this phase of the application?
and/or alternatively how can I detect that currently the script is shutting down because it has successfully ended?
Note: I tested connection_status() but it's useless in my case as it's about connection handling only and merely unrelated. I wonder if there is some function that does the same for the scripts execution status (starting, running, exiting).
Simplified Example Code
This is some very reduced example code to illustrate the issue. Naturally is the error only triggered if it makes sense for the object:
<?php
class TriggerTest
{
public function __destruct()
{
trigger_error('You should have missed something.');
}
}
$obj = new TriggerTest;
exit();
The problem is, that trigger_error() gets executed but the error does not appear anywhere.
How about if you force the error reporting to be a certain setting, trigger the error and then set the error reporting back to it's normal form?
Answer: Just do it. I had some misconfiguration for the error handler and therefore it did not work. My fault.
However it's still interesting if there is any function or similar to determine the execution state on shutdown.

How to halt execution of current PHP script?

I'm writing some simple PHP to back up a microsite. In my controller, I have a quick security/sanity check
if(!preg_match('/^[a-z]$/i', $req)) { gohome(); }
I'd like to continue my the main code after this, but for aesthetics, I'd like to avoid putting the rest of it inside the else block. What's the best way around this? I can think of setting up a fairly simple wrapper to handle authentication and security logic, but I feel like I just missed a really simple solution in my training.
You can use the die/exit function to end the script with (or without) an error.
You could
return gohome();
or
throw new Exception('Request may only contain letters');
Either will stop the execution of that particular script at that point.
If this is in a function, you can usually just return early.
Try the following.
preg_match('/^[a-z]$/i', $req) or die("exit message here, if you'd like");
It's no better functionally than Xavier's but I just like the syntax/idea of "do this or DIE" :) Also kind of makes me think of those old Nintendo games Skate Or Die and Ski Or Die.
exit() is a pretty good way to terminate the current script...
if(!preg_match('/^[a-z]$/i', $req)) { gohome(); exit() }
I prefer to keep exit()/die() calls in the main flow. Or as Phil suggests, throw an Exception and exit() somewhere lower in the stack
You can quite simply just write;
return;
The command will return program control to the calling script, so;
If linear code in an included PHP file, the control will return to the script that invoked the running of that file.
If in a function (or object method) the function will immediately return the argument if supplied, and null if not.
It will not stop the running of the script completely (you need to use exit or die for that) unless there is no calling script.
So in your case;
if(!preg_match('/^[a-z]$/i', $req))
{
gohome();
return;
}
and the else block is not required since it will only continue the script if the condition returns false.

Categories