Solved

why can I not use ELSE like this?

Posted on 2016-09-29
13
45 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
  • 7
  • 3
  • 2
  • +1
13 Comments
 
LVL 2

Accepted Solution

by:
nedlogan earned 250 total points
Comment Utility
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 82

Expert Comment

by:Dave Baldwin
Comment Utility
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 42

Expert Comment

by:zephyr_hex
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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 82

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 125 total points
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 82

Expert Comment

by:Dave Baldwin
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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
 

Author Comment

by:Black Sulfur
Comment Utility
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 42

Assisted Solution

by:zephyr_hex
zephyr_hex earned 125 total points
Comment Utility
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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction HTML checkboxes provide the perfect way for a web developer to receive client input when the client's options might be none, one or many.  But the PHP code for processing the checkboxes can be confusing at first.  What if a checkbox is…
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

728 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now