Avatar of Adam
AdamFlag for United Kingdom of Great Britain and Northern Ireland asked on

Why is my defined string not being up by my function further down in my code?

Hello all,

I have a line in my code which checks to see if the email value entered in a submitted form already exists in the database. If so,  a value of 0 or 1 is assigned to a string and the string value is displayed.

$select = mysqli_query($db_connection, "SELECT `email` FROM `teachers_table` WHERE `email` = '".$_POST['email']."'") or exit(mysqli_error($db_connection));
	if(mysqli_num_rows($select)) {
    $email_exists = '1';
	}  
	else{
		$email_exists = '0';
	}
		echo $email_exists;

Open in new window


This part seems to work as intended - at least the value of 0 or 1 is displayed correctly depending on whether the email exists in the database or not. The next part of my code calls another function, (which in turn calls another validation function) which displays errors.

The validation worked but I added to it:
	if($email_exists == '1') {
      $errors[] = "EMAIL Exists IN OUR DATABASE";
    }

Open in new window


However, when I do this, I get an  Undefined variable: email_exists in... notice / error.

I don't understand why this is coming up as not defined if the function is being called after I have defined this value.  The error message is displayed even though I can see the value of $email_exists (i.e. the 1 or 0) output in the screen.

I've tried removing the quotes, changing to single quotes and using TRUE and FALSE but this didn't appear to change anything.

 When I use '=' instead of '==' i.e:
if($email_exists = '1') {
      $errors[] = "EMAIL Exists IN OUR DATABASE";
    }

Open in new window


...the not defined error goes away but the logic doesn't work, in that $email_exists seems to be always 1 and the error EMAIL Exists IN OUR DATABASE is always displayed.

Any help, as always, much appreciated.

Many thanks,

Adam,
Web DevelopmentHTMLDatabasesPHP* HTML 5

Avatar of undefined
Last Comment
Adam

8/22/2022 - Mon
Julian Hansen

Firstly we cannot tell why you are getting that error because we do not have the full context of your code.

Rule 1 if the compiler tells you it does not exist - then it does not exist.

Variables defined inside one function are not visible to other functions so this is possibly a scoping error. You defined $email_exists in a function or the global scope and then tried to use it in a different function. Variables can only be accessed in the scope they were declared.

We need to see where all your code fits together to tell you exactly where the problem is.

Secondly - this is scary
"SELECT `email` FROM `teachers_table` WHERE `email` = '".$_POST['email']."'"

Open in new window

Apart from the untidy string concatenation (rather use variable embedding or HEREDOC) this code has "HACK ME" written all over it
1. Never trust incoming data - assume everything in $_POST / $_GET etc is a hack attempt and code accordingly
2. Don't embed incoming variables directly into a string without validation and a basic check for existence - goes to rule 1 - assume data is bad and dirty
3. Consider using prepared statements
4. Take a look at the OOP version of MySQLi - in my opinion a much easier implementation to use.

For example

$email = isset($_POST['email'] ? filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) : false;
if ($email) {
  $query = <<< QUERY
SELECT `email` FROM `teachers_table` WHERE `email` = ?
QUERY;
}
if ($stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?")) {

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "s", $email);

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $email);

    /* fetch value */
    mysqli_stmt_fetch($stmt);
}

Open in new window

ASKER CERTIFIED SOLUTION
gr8gonzo

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
gr8gonzo

Sorry, took me a while to write up all that, but Julian's recommendations are spot-on in regards to SQL injection / email sanitation.
ASKER
Adam

Julian, gr8gonzo - thank you both very much for this. I'm going to process it and get back. Just wanted to say thanks first though.

Cheers
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
ASKER
Adam

Many thanks gr8gonzo and Julian,

gr8gonzo - I used the global statement to tell my function to look out for my variable. Thanks for a very clear and not overly technical explanation. It really helped.

Thanks also for your link to the text you wrote on 'Securing Your Web Application' - A very useful read. As you and Julian suggested, I've carried out some protection against SQL injection.

As you recommended, I followed your advice on using TRUE instead of 1. Thanks again for the clear explanation.

Many thanks both and have a good Monday night (or whatever time it may be where you are!)

Adam
Julian Hansen

I used the global statement to tell my function to look out for my variable.
Ouch!
global is a very bad way to solve a scoping problem. It leads to sloppy / bad code design and introduces all manner of side effects not to mention it messes with your testing strategies.

The accepted way of doing what you want is either through parameters (dependency injection) or through encapsulation (class) - but avoid using global.
gr8gonzo

Yep, I agree. I added the global explanation in there so you'd be aware of options, but as I mentioned after presenting that option, "Either way will work, although it's usually better practice to pass things in as parameters."

When you get into object-oriented PHP, scope usually becomes a lot easier to manage, but that's a topic for another day.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Adam

Thanks both. I'm pretty sure most of my code is bad . I have a habit of doing the easiest (often worst) way of doing things if it looks like it achieves what I'm after. I'd like to hope I'll re-visit my project when I've learned more about coding and clean up all the ugly code. I've still not looked at OO PHP and when I see OO written php code it usually stumps me.

Cheers,
Adam
Julian Hansen

Coding is a continual learning process.

Good coding style is a logical step as it saves you time and frustration.

OOP may be intimidating but take an hour to look at it today and it will be less intimidating tomorrow - invest some time in every day and in a very short space of time you will be on top of it.

It is all about making the unfamiliar - familiar. We tend to gravitate to what we know - new things are scary so we avoid them. Good coders do the opposite - they see something new they dive in and make the unfamiliar - familiar.

Do that a few times and it becomes a habit - new things stop being intimidating and become interesting and exciting. The key thing is taking that first step and jumping into the unfamiliar.
ASKER
Adam

Wise words. Thanks for the encouragement!
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23