Solved

why can I not use ELSE like this?

Posted on 2016-09-29
13
55 Views
Last Modified: 2016-10-01
Just when I think I am getting the hang of it I get stuck on simple stuff. Why can I not use ELSE like below? It is giving me an "unexpected 'else'" error.

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} else {
		
		// do something
		
	} else {
		
		//do something else
	} 
}

Open in new window

0
Comment
Question by:Black Sulfur
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
  • 2
  • +1
13 Comments
 
LVL 2

Accepted Solution

by:
nedlogan earned 250 total points
ID: 41822476
It's because you cannot have else else. Two competing elses.

You need to do this:

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} elseif(//some other case){
		
		// do something
		
	} else {
		
		//last option here
	} 
}

Open in new window

0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 41822565
php.net is always your friend in these matters.  It is also the 'official' word.
http://php.net/manual/en/control-structures.elseif.php
0
 
LVL 43

Expert Comment

by:zephyr_hex (Megan)
ID: 41822602
That actually has nothing to do with PHP, and everything to do with logic.  Multiple unqualified else clauses defy logic.

If you think about the flow of logic, how would someone know when to take the first unqualified else versus the second one?  You need to specify a condition on the first unqualified else so there is logic behind when that is the correct path to take.

You can think of an unqualified else as meaning "everything else should take this path".
1
Secure Your WordPress Site: 5 Essential Approaches

WordPress is the web's most popular CMS, but its dominance also makes it a target for attackers. Our eBook will show you how to:

Prevent costly exploits of core and plugin vulnerabilities
Repel automated attacks
Lock down your dashboard, secure your code, and protect your users

 
LVL 1

Author Comment

by:Black Sulfur
ID: 41822914
Thanks for your responses. i didn't try 'elseif' because I thought you only used it if the conditions you were using it for would be true. But they could be true or false?

if (condition) {
    code to be executed if this condition is true;
} elseif (condition) {
    code to be executed if this condition is true;
} else {
    code to be executed if all conditions are false;
}

Open in new window


I don't have all my code with me as I am using a different PC at the moment but I will try to illustrate what I am doing and if that isn't enough I can post my actual code later.

So, taking my original code, I have commented on what is supposed to happen

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} else {
		
		// check email address and password in database. If count of failed logins exceeds 5, lock the user out for a period of time.
		
	} else {
		
		//The login fails and count is less than 5. +1 is to be added to failed login count for particular email address. If there is no record then a new one is to be inserted. 
	} 
}

// Then I still need another condition to actually log the user in if the email/password combination is correct.

Open in new window


I have most of the code that does all of this except for the timing part which I am still working on but otherwise it all works. I just don't know how to structure it with else and elseif etc.
0
 
LVL 83

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 125 total points
ID: 41822934
If you look at the 'man' pages, the 'if/else' construct only supports one else to go with the if.  This is the correct usage.  The 2nd condition can be a negative test where for example something is not equal to something else like ($thing != 99).  The condition is 'true' if $thing is Not Equal to 99.  
if (condition) {
    code to be executed if this condition is true;
} elseif (condition) {
    code to be executed if this condition is true;
} else {
    code to be executed if all conditions are false;
}

Open in new window


In your example, you might use ($count > 5).  You would probably get the value of $count before you enter the 'if' section so it would be available to the 'condition' you want to check.
0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41823056
It is making a bit more sense now, or at least I think it is. I should use elseif and like you said, I can just check for it not being equal and not only being equal. So, for example, instead of checking if inputs are empty and then outputting a validation error, I could check that they aren't empty instead, do a bunch of stuff and then use the else at the very end to output the validation error because they didn't enter an email or password. is that right or have I totally lost the plot here?
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 41823092
No, I think you're understanding it better.  I would keep the 'empty' check as the first 'if' though.  If either of them is empty, there is no reason to go on to the other checks.

I often have to try more than one comparison to get the right one because inverse logic is sometimes confusing to me.  Having multiple conditions to check makes it even more confusing sometimes.
0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41823547
Yeah, that is how it has always made sense to me thus far. Before I even worry about what is going to happen if the submission is okay, I want to deal with what happens if there is something wrong first.

I will try apply what everyone has said and see how I get on with my code. I Will post the actual code if I still get stuck and let you guys know.
0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41823640
Guys, I think I am worse off than before, lol. And I am probably a hopeless case but I'm going to keep trying anyway. I understand if people get too frustrated with me to help but I am going to post the code just in case someone has patience. This still isn't everything because I am trying to get it to work bit by bit. This does not do what it is supposed to do. All this actually does is update the failed count if the email address is already in the database. I can't login with successful details, it doesn't insert new records and does not display any messages. I a word, it's a flop!  :-/

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} 
	
	elseif($stmt = $link->prepare("SELECT `failed_email`, `fail_count` FROM `failed_logins` WHERE `failed_email` = ?")){
	$stmt->bind_param("s", $email);
	$email = $_POST['email'];
	$stmt->execute();
	$result = $stmt->get_result();
	$numRows = $result->num_rows;
	if($numRows > 0){
		$row = $result->fetch_assoc();
		$failed_email = $row['failed_email'];
		$db_fail_count = $row['fail_count'];
		$stmt->close();
		
		
		$stmt = $link->prepare("UPDATE `failed_logins` SET fail_count = ?, login_dt = ? WHERE failed_email = ?");
		$stmt->bind_param("iss", $fail_count, $login_dt, $email);
		$fail_count = $db_fail_count + 1;
		$login_dt = Carbon::now();
		$stmt->execute();
		$stmt->close();
		
		}
		
	} elseif($stmt = $link->prepare("INSERT INTO `failed_logins` (ip_address, failed_email, login_dt, fail_count) VALUES (?, ?, ?, ?)")){
		$stmt->bind_param("sssi", $ip_address, $email, $login_dt, $fail_count);
		$ip_address = $_SERVER['REMOTE_ADDR'];
		$login_dt = Carbon::now();
		$fail_count = 1;
		$stmt->execute();
		$stmt->close();
		
		echo $failed_login_message = "<p class='contact-error'>Invalid login credentials</p>";
		}	
		
	else {
		
		$stmt = $link->prepare("SELECT `user_password`, `safe_user_id` FROM `db_users` WHERE `user_email` = ? AND `user_active` = ? ");
		$stmt->bind_param("si", $email, $user_active);
		$email = clean_user_input($_POST['email']);
		$user_active = 1;
		$stmt->execute();
		$result = $stmt->get_result();
		if($result) {
			
		$row = $result->fetch_assoc();
			$db_password = $row['user_password'];
			$password = $_POST['password'];
			if(password_verify($password, $db_password)){
				
				//clear failed logins function here
				echo "Found a match, you can log in!";
				$stmt->close();
		
			}
		}
	}
}

Open in new window

0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41823658
I am trying this now. Am I on the right track?

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} elseif(!$message){
		
		$stmt = $link->prepare("SELECT `failed_email`, `fail_count` FROM `failed_logins` WHERE `failed_email` = ?");
	$stmt->bind_param("s", $email);
	$email = $_POST['email'];
	$stmt->execute();
	$result = $stmt->get_result();
	$numRows = $result->num_rows;
	if($numRows > 0){
		$row = $result->fetch_assoc();
		$failed_email = $row['failed_email'];
		$db_fail_count = $row['fail_count'];
		$stmt->close();
		
		
		$stmt = $link->prepare("UPDATE `failed_logins` SET fail_count = ?, login_dt = ? WHERE failed_email = ?");
		$stmt->bind_param("iss", $fail_count, $login_dt, $email);
		$fail_count = $db_fail_count + 1;
		$login_dt = Carbon::now();
		$stmt->execute();
		$stmt->close();
		
			} elseif($numRows < 1){
		
					echo "insert record now because no records found";
		}
	}
}

Open in new window

0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41823895
UPDATE: I now having everything working but I just have to add the part that locks the user out :)

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} 
	
	else {
		
		$stmt = $link->prepare("SELECT `user_password`, `safe_user_id` FROM `db_users` WHERE `user_email` = ? AND `user_active` = ? ");
		$stmt->bind_param("si", $email, $user_active);
		$email = clean_user_input($_POST['email']);
		$user_active = 1;
		$stmt->execute();
		$result = $stmt->get_result();
		if($result) {
			
		$row = $result->fetch_assoc();
			$db_password = $row['user_password'];
			$password = $_POST['password'];
			if(password_verify($password, $db_password)){
				
				
				$stmt = $link->prepare("UPDATE `failed_logins` SET `fail_count` = ? WHERE `failed_email` = ?");
				$stmt->bind_param("ss", $fail_count, $email);
				$fail_count = 0;
				$email = $_POST['email'];
				$stmt->execute();
				$stmt->close();
				$message = "<div class='contact-success'>You can log in</div>";		
				
			} else {
				
				$stmt = $link->prepare("SELECT `failed_email`, `fail_count` FROM `failed_logins` WHERE `failed_email` = ?");
				$stmt->bind_param("s", $email);
				$email = $_POST['email'];
				$stmt->execute();
				$result = $stmt->get_result();
				$numRows = $result->num_rows;
				if($numRows > 0){
				$row = $result->fetch_assoc();
				$failed_email = $row['failed_email'];
				$db_fail_count = $row['fail_count'];
				$stmt->close();
				
				
				$stmt = $link->prepare("UPDATE `failed_logins` SET fail_count = ?, login_dt = ? WHERE failed_email = ?");
				$stmt->bind_param("iss", $fail_count, $login_dt, $email);
				$fail_count = $db_fail_count + 1;
				$login_dt = Carbon::now();
				$stmt->execute();
				$stmt->close();
				$message = "<p class='contact-error'>Invalid login credentials</p>";
					
			} elseif($numRows < 1){
					
					$stmt = $link->prepare("INSERT INTO `failed_logins` (ip_address, failed_email, login_dt, fail_count) VALUES (?, ?, ?, ?)");
					$stmt->bind_param("sssi", $ip_address, $email, $login_dt, $fail_count);
					$ip_address = $_SERVER['REMOTE_ADDR'];
					$login_dt = Carbon::now();
					$fail_count = 1;
					$stmt->execute();
					$stmt->close();

					$message = "<p class='contact-error'>Invalid login credentials</p>";
				}
			}
		}
	}
}

Open in new window

0
 
LVL 1

Author Comment

by:Black Sulfur
ID: 41824172
Finally, I got it working. Man, that was tricky. I still need to refine it and create the lockout time or do something else. Still deciding what I want to happen, perhaps display my least favourite thing in the world (CAPTCHA) or make them answer a security question, reset their password via email, who knows? I am also just playing around with sleep() as I read that is a good way to slow hackers down.

Anyway, when I can see straight again I will try neaten it up and make it less verbose (new word I leant recently :P )

If anyone would like to show me how to make this code better, please do! I always want to do things the best way possible.

$message = "";
if(isset($_POST['login'])) {
	
	if(empty($_POST['email']) || empty($_POST['password'])) {
		
		
		$message = "<div class='contact-error'>Please enter your email and password</div>";		

	} 
	
	else {
		
		$stmt = $link->prepare("SELECT `fail_count` FROM `failed_logins` WHERE `failed_email` = ?");
		$stmt->bind_param("s", $email);
		$email = $_POST['email'];
		$stmt->execute();
		$result = $stmt->get_result();
		if($result){
			
			$row = $result->fetch_assoc();
			$failed_login_count = $row['fail_count'];
			if($failed_login_count > 5){
				

				$message = "<div class='contact-error'>Too many login attempts</div>";
				
			} elseif($failed_login_count <5) {
				
				$stmt = $link->prepare("SELECT `user_password`, `safe_user_id` FROM `db_users` WHERE `user_email` = ? AND `user_active` = ? ");
				$stmt->bind_param("si", $email, $user_active);
				$email = clean_user_input($_POST['email']);
				$user_active = 1;
				$stmt->execute();
				$result = $stmt->get_result();
				if($result) {
			
				$row = $result->fetch_assoc();
				$db_password = $row['user_password'];
				$password = $_POST['password'];
				if(password_verify($password, $db_password)){

				
				$stmt = $link->prepare("UPDATE `failed_logins` SET `fail_count` = ? WHERE `failed_email` = ?");
				$stmt->bind_param("ss", $fail_count, $email);
				$fail_count = 0;
				$email = $_POST['email'];
				$stmt->execute();
				$stmt->close();
				$message = "<div class='contact-success'>You can log in</div>";		
				
					} else {
				
				$stmt = $link->prepare("SELECT `failed_email`, `fail_count` FROM `failed_logins` WHERE `failed_email` = ?");
				$stmt->bind_param("s", $email);
				$email = $_POST['email'];
				$stmt->execute();
				$result = $stmt->get_result();
				$numRows = $result->num_rows;
				if($numRows > 0){
				$row = $result->fetch_assoc();
				$failed_email = $row['failed_email'];
				$db_fail_count = $row['fail_count'];
				$stmt->close();
				
				
				$stmt = $link->prepare("UPDATE `failed_logins` SET fail_count = ?, login_dt = ? WHERE failed_email = ?");
				$stmt->bind_param("iss", $fail_count, $login_dt, $email);
				$fail_count = $db_fail_count + 1;
				$login_dt = Carbon::now();
				$stmt->execute();
				$stmt->close();
				$message = "<p class='contact-error'>Invalid login credentials</p>";
				sleep(2);
					
			} elseif($numRows < 1){
					
					$stmt = $link->prepare("INSERT INTO `failed_logins` (ip_address, failed_email, login_dt, fail_count) VALUES (?, ?, ?, ?)");
					$stmt->bind_param("sssi", $ip_address, $email, $login_dt, $fail_count);
					$ip_address = $_SERVER['REMOTE_ADDR'];
					$login_dt = Carbon::now();
					$fail_count = 1;
					$stmt->execute();
					$stmt->close();
					sleep(2);
					$message = "<p class='contact-error'>Invalid login credentials</p>";
				
						}
					}
				}
			}
		}
	}
}

Open in new window

0
 
LVL 43

Assisted Solution

by:zephyr_hex (Megan)
zephyr_hex (Megan) earned 125 total points
ID: 41824282
One thing that I find makes code more readable is to reverse conditions where there is no else clause, and no other code that is run after the condition.  For example, here in your code:

if($result){
    //stuff happens
} // nothing else happens after this point

Open in new window


I would write it as:

if(!$result) { return; }
//stuff happens

Open in new window


I find this reduces the number of nests and brackets, which IMO, makes code easier to read.
0

Featured Post

WordPress Tutorial 4: Recommended Plugins

Now that you have WordPress installed, understand the interface, and know how to install new parts, let’s take a look at our recommended plugins.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

632 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question