Replacement for nested IF's? - php

Sometimes mostly for processing user input i find myself using a lot of IF statements nested in each other, sometimes it is much more than below, to the point it goes from if on left side of screen to the if number 10 on right side of screen.
This is very difficult to read and troubleshoot, is there other way to do nested if?
I know about switch() however in this case i have to do query in third if rather than first.
if (true) {
if (true) {
if (true) {
...
echo "You are logged in";
} else {
echo "login failed"
}
} else {
echo "incorrect email";
}
}

I assume that your true conditions are real conditions, and not just the true boolean constant.
if (condition1 && condition2 && condition3) {
echo "You are logged in";
} else {
echo "login failed";
}
If you need a condition handled separately:
if (emailAddressIsCorrect) {
if (condition2 && condition3) {
echo "You are logged in";
} else {
echo "login failed";
} else {
echo "incorrect email";
}
Or you can just return early, which is cleaner in my opinion. You can do this for each condition, if you like. You can have as many conditions as you want with this arrangement, without requiring condition nesting:
if (!emailAddressIsCorrect) {
echo "incorrect email";
return;
}

Often times I'll do the "fail out" strategy instead:
function login() {
if (!condition1) {
echo "incorrect email";
return false;
}
if(!condition2) {
echo "incorrect password";
return false;
}
if(condition3) {
echo "logged in successfully!";
return true;
}
return false;
}
This example is suspect, there are security concerns with letting an attacker know which part of the login failed, but as a code snippet, you can see the strategy.

Combine 2 if statements using "&&".
OR
Sometimes using object oriented programming you can avoid if statements:
if(is type a) {
dostuff1();
} else if(is type b) {
dostuff2();
}
With classes and inheritance:
class->dostuff();
You can also use "first class functions" to avoid if statements.
Say you have values $_POST['page'] == 'page1', $_POST['page'] == 'page2'
$functions = array("page1"=>$function1, "page2"=>$function2);
function dostuff1() {
return 'a';
}
function dostuff2() {
return 'b';
}
$function1 = "dostuff1";
$function2 = "dostuff2";
$functions[$_POST['page']]();
instead of
if($_POST['page'] == '1') dostuff1();
etc... although this method is somewhat scary... lol

compare this:
if ($true1) {
if ($true2) {
if ($true3) {
...
with this:
if ($true1 && $true2 && $true3) {
...
}
with the first appoach not only you're wasting useful space for a single IF,
you are also delaying the inevitable: the optimization at a later day.
Also, it has no matter (etc. performance) if you place your IFs as nested or
in a single line because PHP intepreter will stop checking beyond if it finds
a FALSE.

Related

PHP: Is there an alternative to using multiple if-statements?

I am in the making of some code that needs to check if a users login details are correct, and I therefore need a lot of if-statements inside each other. If any of the conditions in the if-statements are not true, they should alle return the same value. Is there an easy way of doing this, instead of writing the same multiple times? I have made an example below to visualize my problem. As you can see here I write " else { return false; }" multiple time, and this is what I am wondering if you are able to do more efficiently. Maybe so I only have to write "or else return false" once.
//some code
if (/*some condition*/) {
//some code
if (/*some new condition*/) {
//some code
if (/*some new condition*/) {
//some code
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
I am having a hard time finding a good way to explain my problem, so if you have a more elegant way of explaining it, do not hesitate to edit my post. I am also not quite sure that the title is as good as it could be, so if you have any ideas to an alternativ please say so :)
Lets say you have something like that (I added No):
if ( condition1 ) {
//some code 1
if ( condition2 ) {
//some code 2
if ( condition3 ) {
//some code 3
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
Since each time a condition is false, you exit the function returning false, you can directly test if the condition is false using a negation (if the negated condition is true):
if ( !condition1 ) {
return false;
}
//some code 1
if ( !condition2 ) {
return false;
}
//some code 2
if ( !condition3 ) {
return false;
}
//some code 3
This doesn't reduce the number of if statements, but you avoid many nesting levels and the else statements.
You can also try the switch statement. For many situations it will produce cleaner code.
<?php
if ($i == 0) {
echo "i equals 0";
} elseif ($i == 1) {
echo "i equals 1";
} elseif ($i == 2) {
echo "i equals 2";
}
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
?>
The switch statement is also compatible with using strings:
<?php
switch ($i) {
case "apple":
echo "i is apple";
break;
case "bar":
echo "i is bar";
break;
case "cake":
echo "i is cake";
break;
}
?>
Good luck! :)

How to have an else statement after a loop with an if statement?

I am trying to make a registration system with text files and I need help with using an else statement after the loop that checks if the username is taken.
I am generally just trying to find out how to have an else statement after a loop with an if statement, if I find out that out my problem is basically solved. Here is the code:
while($i < count($logindata)-1) {
if ($_POST['username'] == $user[$i]['username']) {
set_message(" That username is taken", "danger");
}
$i++;
}
else {
if (!empty($_POST['username']) && !empty($_POST['password'])) {
file_put_contents('logininformation.txt', $_POST['username'] . "?=%&$##[}[}+-789409289746829" . $_POST['password'] . "\n", FILE_APPEND);
set_message("Account created!", "success");
} else {
set_message(" You have not put in a username and/or password","danger");
}
}
I expect to be able to have an else statement after the loop and it working.
A loop is not a condition, therefore it does not have an else part either. It is correct that the loop runs while the condition evaluates to true, but as soon as the condition does not evaluate to true, the loop is ended.
Therefore, to check whether the loop was not triggered at all, you have to find a different way, e.g. write a condition on its own.
For the sake of argument, you COULD save a flag and evaluate that afterwards, but in most cases I would not recommend that:
$i = 0;
$loopDidRun = false;
while ($i < 10) {
$i++;
$loopDidRun = true;
}
if (!$loopDidRun) {
echo "loop did not run, therefore the 'else case', but not really";
}
Your logic is severely flawed.
$failed=false;
if(empty($_POST['username']) || empty($_POST['password'])){
$failed=true,
set_message(" You have not put in a username and/or password","danger");
}else{
while($i<count($logindata)-1){
if($_POST['username']==$user[$i]['username']){
$failed=true;
set_message("That username is taken","danger");
break;
}
$i++;
}
}
if(!$failed){
file_put_contents('logininformation.txt',$_POST['username']."?=%&$##[[}+-789409289746829".$_POST['password']."\n",FILE_APPEND);
set_message("Account created!","success");
}
However all I am doing here is fixing bad code. Before anything you need to filter the $POST input given to disallow just any input, passwords etc. should not be stored in plain text, and this is not the proper way of creating a factory for this. You should find better, and secure, examples online and work from them.

If statement inside another one is false, return to the else of original if statement

Is there any way in PHP to return at else of first statement, if the second statement which is inside of first, is false
if($first == true) {
//other code which is not necessary to mention here!
if($second == true){
// do smth
}
else{
return to the else of $first statement
}
//other code which is not necessary to mention here!
}
else{
//do smth else
}
Yes, there are multiple ways. For starters, just combine both the statements and give another condition:
if ($first == true && $second == true) {
// do smth
} elseif ($first == true && $second == false) {
// else of$first statement
} else {
//do smth else
}
This can be used as a guidance to get an idea to start. But if you can get a real world example, there can be conditions grouped, tailored to your requirement.
While there is no native way to jump to outer elses from an inner else, but you can set a flag for later processing:
$do_else = false;
if($first == true) {
//other code which is not necessary to mention here!
if($second == true){
// do smth
}
else{
$do_else = true;
}
//other code which is not necessary to mention here!
}
else{
$do_else = true;
//do smth else
}
if($do_else){
//do smth else
}
If the answers above doesn t help you in the real situation, you can create a function for execute in 'else' statements to avoid code duplication

Problem with Boolean Values in PHP

I've some problems with handling Boolean values in PHP. It is a validation script before storing data into database. I wrote a global validator that will validate and return a Boolean value whether the validation was successful .
Here is my code.
//VALIDATE
$isValid = true;
foreach($team as $key=>$val) {
if(!is_array($val)){
$isValid = $isValid && validate($val, $key);
}
}
for($it=0;$it<count($team['members']);$it++){
foreach($team['members'][$it] as $key=>$val) {
$isValid = $isValid && validate($val, $key);
}
}
if(!$isValid) { // EDITED: if(!isValid)
echo "validation error";
exit(1);
}
//END OF VALIDATE
The validate function is working properly but sometimes I end up getting $isValid = true or the other way, when I try with some test cases.
Hmm.. What am I doing wrong here ?
Please check, if this form does the trick:
if( false === $isValid) {
echo "validation error";
exit(1);
}
Note, that ( ! $isValid ) or (false == $isValid ) in some cases return results, which are at first look wrong. See for example the hint in the strpos() documentation.
In fact, the results are fine, since operations line ! or == try to cast operands in a 'useful' way.
That said, it's always better to user the === operator, since it checks values and types of operands. Please see operator overview.
if(!isValid) { falls back to if (!"isValid"), if there is no constant isValid. You probably meant if (!$isValid) {.
if(!isValid) {
isValid has no dolar, (you need to give variables in PHP some cash) so:
if(!$isValid) {
Source : http://bit.ly/1hxDmVR
Here is sample code for working with logical operators in PHP. Hope it will helpful:
<html>
<head>
<title>Logical</title>
</head>
<body>
<?php
$a=10;
$b=20;
if($a>$b)
{
echo " A is Greater";
}
elseif($a<$b)
{
echo " A is lesser";
}
else
{
echo "A and B are equal";
}
?>
<?php
$c=30;
$d=40;
//if(($a<$c)AND($b<$d))
if(($a<$c)&&($b<$d))
{
echo "A and B are larger";
}
if(isset($d))
$d=100;
echo $d;
unset($d);
?>
<?php
$var1=2;
switch($var1)
{
case 1:echo "var1 is 1";
break;
case 2:echo "var1 is 2";
break;
case 3:echo "var1 is 3";
break;
default:echo "var1 is unknown";
}
?>
</body>
</html>
I think the problem is that your $isValid variable can be changed many times in the loops and by the end of your code simply applies to the last value in your final loop.
You should set it to true initially and then only set it to false IF your validity check fails - not simply assign its value based on every single validity check.

Need help checking if else statement for { }

Somewhere along the line I'm adding or leaving out a { } but I just can't figure out where
<?php
if (file_exists('config.php')) {
require_once('config.php');
{
if ( $EDITED_CONFIG == false )
{
header("Location: welcome.php");
}
}
}
else (file_exists('default-config-new.php')) {
require_once('default-config-new.php');
{
if ( $EDITED_CONFIG == false )
{
header("Location: welcome.php");
}
}
}
?>
If file exists require it and if edited = false redirect, if true end script.
else
If file exists require it and if edited = false redirect, if true end script.
So if the first file doesn't exist it mustn't require it or look for edited, it must skip to the second file and if that exists it must checked edited and then if is false then redirect. If the first file is true it must end script and load page. So it mustn't check second file if first file is true.
Also is this the lightest way to do this?
Thanks
If you indent your code properly, your error will become evident.
A few links that may be useful:
Wikipedia: Indent style
How to indent code
PHP Coding standard: Indentation
You're not closing your if statements: Should be something like:
<?php
if (file_exists('config.php')) {
require_once('config.php');
if ($EDITED_CONFIG == false) {
header("Location: welcome.php");
}
}
else{
require_once('default-config-new.php');
if ($EDITED_CONFIG == false) {
header("Location: welcome.php");
}
}
?>
Edited. Also, you need to close brackets around all code to be executed for that statement, before you can use another elseif or else statement:
if ($x == 1) {
echo "X is 1!";
}
else if ($x == 0) {
echo "X is 0!";
}
else {
echo "Not 1 or 0!";
}
You are missing the { after the else to enclose what you want inside the "else" block i believe
You need to write
else if (conditions...)
You have got
else (conditions...)

Categories