PHP exit, return & proper programming standards - php

Is it ok to include a break or exit command to prevent further code from executing or is this bad programming?
function index()
{
$error = NULL;
if ($_POST){
// validate form
if ($form_validated) {
echo 'this content only';
exit; // or return IS THIS BAD???
} else {
$error = 'form failed';
}
}
echo 'normal page on initial load';
if ($error) { echo '<br />'.$error; }
}

It is OK to prevent further code from executing using exit.
Having said that, whether this is the best way to do it in this particular example is debatable. It is typical to use exit when issuing redirects:
header('Location: /foo');
exit;
In your case, there doesn't seem to be an immediate need to stop the program execution in mid run. You should rather structure your program flow so it always completes, but with different results. It is hard to follow program logic which may terminate somewhere in the middle, so a more logical flow that returns from functions or branches using if..else is usually preferable.

For the example you give:
function index()
{
...
if ($form_validated) {
echo 'this content only';
exit; // or return IS THIS BAD???
} else {
...
}
This is normally called early exit or early return (return is more common). This can be very okay, some people say that early returns make code hard to understand but I'd say it depends on a lot more if a function can be easily read and understood or not.
So the person who decides here whether it is bad or not is you. You need to find some criteria on your own where you draw the line. For example if a function is long (more than 12 lines of code) and contains many of these early returns or even exits, this will make the code more complicated.
Generally early returns can make a functions code less complex which can heavily reduce the number of bugs.
So probably the complexity is a good criteria here.
Additionally I suggest you use exit very carefully. It does much at once and you should normally not need it within your program flow. Especially if you're writing business logic.

Related

after early return does next code execute

I have php file where i use if statments and i call this file via ajax.. onSuccess it gives me result if file is upload successfully or error.
Code look like this:
if(empty($_FILES['file']['name'])){
return "no image was selected";
}
if($two_many_images){
return "Only x images are alowed to upload";
}
if($size>2014522){
return "Size error";
}
foreach($_FILES["file"]['tmp_name'] as $key=>$imgLocation){
uploadImage($_FILES["fileToUpload"]['tmp_name'][$key], $imgLocation);
}
Question : In first if statment condition is true, wil my second if statment execute ?
This can be easily demonstrated, for example you have a function:
funciton foo(){
echo "foo\n";
return;
echo 'bar';
}
if you call
foo();
It will print out
foo
But not bar. Once execution pointer hits the return it will return back to where foo() was called from. This can also be easily shown.
foo();
foo();
foo();
Prints
foo
foo
foo
UPDATE: based off your comments the correct way to do what you want is this
if(empty($_FILES['file']['name'])){
echo "no image was selected";
exit();
}
if($two_many_images){
echo "Only x images are alowed to upload";
exit();
}
if($size>2014522){
echo "Size error";
exit();
}
foreach($_FILES["file"]['tmp_name'] as $key=>$imgLocation){
uploadImage($_FILES["fileToUpload"]['tmp_name'][$key], $imgLocation);
}
I use exit() instead of return, because it's more readable and makes more sense, even though in your case return has the same effect. Exit will completely end execution for php, which is really what you want. You could also do something like
die( 'Message' );
Or
exit( 'Message' );
As well which will exit and output the message. They are all pretty much the same... I put echo first just because it always feels a bit dirty to me to put stuff in exit. Not sure why that is, maybe it I link it to unintended behavior because of seeing die() so much at the top of files not meant to be ran outside of framework. But I digress.
Just for the sake of completeness, based of your comments, if you call return from the global scope in PHP, it has no where to return to so execution just halts at that point. The reason it's better to use exit or die is that return has distinctly different behavior, which is to 'return' data from a function call. So it's more readable to use the method who's behavior best matches what you want. That being to end execution of the current script ( PHP instance ).
No, your second statement will not be executed. When the return is invoked, the rest of the code will not be executed. The PHP documentation says:
If called from the global scope, then execution of the current script file is ended.

Using the die() function excessively

Is it bad programming practice to use the die(); function excessively when validating data in PHP?
I am building a class where I have used that function more than a dozen times, so that if the validation test fails the entire script dies. Is that good practice, is there a better way I should be doing it? Does this practice vary between languages, are there any programming-wide conventions or best-practices to learn from?
Here's an example:
if($error = $this->checkDate($start)){
echo "START: ".$error."\r\n";
die();
}
if($error = $this->checkDate($end)){
echo "END: ".$error."\r\n";
die();
}
if($start>$end){
$error = "The start date must come <i>after</i> the end date!";
echo $error;
die();
}
if(($end-$start)<(3*24*3600) || ($end-$start)>(3*30*24*3600)){
$error = "The period must be at <i>least</i> 3 days long, and at <i>most</i> 3 months long. This date spans about ".round(($end-$start)/(3600*24*30))." months.";
echo $error;
die();
}
etc, etc, etc...
PS - How is "best-practice" not a tag already??
If you are building a bigger system you probably want more output even if it fails, like templating and such. The way you terminate here would make that hard to accomplish in a clean way.
If your application is intended to be really small, so you would not need to do anything after this validation, you are probably good, but then again you should always build code that is easily extendable in case you need to do so later.
If it were up to me, I would probably throw an exception instead and then handle the exception apropriatly at a higher nesting level.
But then again you will need to make the call yourself based on what your actual intent with this application is. Maybe it is appropriate, but probably not.
There are actually two critical flaws in your approach:
as a matter of fact, there should be not a single die() statement in the production code.
also, no class method should output a word.
Speaking of form validation - your idea of it makes user experience hard and outdated. A good web-site will always show on arror
a form itself
all the entered data
all the errors at once, to let user fix them all, not submit the form again and again until they get to the last error.

Using too many exits a good practise? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Say I have made an ajax request to a php file. when the result is success or something other. I do not need my server to go through the rest of the code. So I was thinking to use exit function but having too many exits a good practise ? I am not sure.
if(some condition) exit("success");
else if(some condition) exit("fail");
// after some 3 lines or so
if(fail) exit("error");
Using too many exit functions in PHP is a good or bad practice. Could anyone tell me are there any restrictions on using exit function? I have been told that you cannot use too many return statements in a function and I was thinking may be even exit must not be used more frequently. Using too many exit functions a wrong way of doing things?
Update
When it has satisfied the given requirement, there is no need for further execution of code. I don't want my server to go down and meet the end I could simply exit. It makes faster I guess?
I prefer to have multiple exit messages, drawing a correlation between having multiple return statements in a method.
If you did not have multiple exit messages, I think your code would be kind of ugly:
$retCondition = "success";
if(!some condition) {
if(some condition 2) $retCondition = "fail";
else {
..Your code
}
}
exit($retCondition);
This is kind of a php solution, but you get the idea.
To me it is wrong practice. If possible one entry point and one exit point - it's irrelevant what language it is. I care my time and such approach simply help reading, maintaining and debugging code.
EDIT
To summary my point here (or follow the comments): this is not black/white case, so you never should be really 100% strict, but I tend to avoid early returns if I find this causing readability loss and this is a sufficient reason for me but also I sometimes agree to do the opposite if the code whould simply look like xmas tree with all nested if()/else blocks.
I prefer to use Exception and only use exit if redirecting using headers
try {
if (! $conditionA) {
throw new Exception(" Fail ConditionA");
}
if (! $conditionB) {
throw new Exception(" Fail ConditionB");
}
header("Location: xxx");
exit();
} catch (Exception $e) {
echo $e->getMessage();
}
Using exit is a bad practice. It should only be used if crucial code fails for example:
<?php defined('FOO') or exit('Foo not set');?>
<?php mysql_connect('usr','pwd','host') or exit('could not connect');?>
For normal circumstances for example the 'if' statement:
if (condition) {
echo 'Hello';
} else {
callSomeFunction();
}
Let's say you have a fooBar function:
function fooBar () {
if (condition) {
return 'Hello';
} else {
return FALSE; // If you use return the function 'fooBar' stops at that point
echo 'Hello?'; // This is not executed because we already returned.
}
}
Good luck
It doesn't cause any problem, but it's nice to have just one exit point. It may make debugging easier. You can do it this way:
if(some condition) $error_msg = "success";
else if(some condition) $error_msg = "fail";
// after some 3 lines or so
if(fail) $error_msg = "error";
if($error_msg != '') exit($error_msg);
If you are using a true object oriented style it should be structured similar to the following
function foo($x){
if (!is_int($x)) throw new Exception('foo needs an int argument');
return $x *2
}
Now there is only one return and when you call the method you use
$variable = 0;
try{
$variable = $this->foo(2.5);
}catch(Exception e){
print_r($e)
}
which allows you to see the problem and handle it in a controlled way.
it follows the flow chart way of having 1 "start" and 1 "end" but allows very verbose messages to be displayed etc

PHP exit() vs if - else statement

Is it a good or bad practice to authenticate and then just exit() the function or to wrap the whole result of the authentication in an if statement? Example
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false) exit();
//continue with senstive code here
}
}
OR
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == true)
{
// do sensitive stuff
}
}
I would like to take this opportunity to talk about exit; (as others have stated both work, the second is more explicit then the first, and give you the opportunity to send a nice error message to the user). My main beef (I have several with exit;) is that people should stop using it in libraries, i.e. code that can/will be used in other projects... You know how irritating it is to debug those? Throw exceptions, trigger fatal errors, but give me something with a description.
/rant
Your examples are equivalent.
However, it's not usually useful to the end user to just exit the script abruptly. Instead, send your user a useful error message printed in HTML rather than the plain text you would get from a die() call, for example.
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false)
{
$errormsg = "You are not allowed to view this page";
}
else
{
//continue with senstive code here
}
}
Later, print the error in HTML, rather than just aborting the script:
<div class='error'><?php echo $errormsg; ?></error>
Either or. I don't think it'll make a difference. It relatively the exact same thing. In programming there are many ways to program things, never on right way in most instances.
They are absolutely the same. The indentation and coding style is the only difference. In both cases the sensitive code won't execute unless the authentication is done successfully.
It's usually better to be expressive in your code though, so I'd recommend the second method.

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