1

I have a simple demo php scripts am trying out. i have been using the deprecated mysql_ extensions earlier, trying to migrate from that to mysqli_ is being overly buggy. when trying to use mysqli_real_escape_string php throws a variable not defined error cant seem to figure out why.

    <?php

$servername = "localhost";
$username = "root";
$password = "";
$dbname = "bridgoo";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);


// Check connection
if ($conn->connect_error) {
  //do stuff
  }
// prepare and bind
$stmt = $conn->prepare("INSERT INTO bridgoo_users (username, email, password) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $username, $password, $email);


    //generate password hash using blowfish algorithm
   $password_hash =  password_hash($_POST['password'], PASSWORD_BCRYPT, ["cost" => 9]);

$username = clean_input($_POST['username']);
$password = clean_input($password_hash);
$email = clean_input($_POST['email']);


function clean_input($input){

    $input = htmlentities($input);
    $input = htmlspecialchars($input,ENT_QUOTES);
    $input = mysqli_real_escape_string($conn,$input);

    return $input;
}


$stmt->execute();
$stmt->close();
$conn->close();

?>

php error Notice: Undefined variable: conn in C:\xampp\server1\htdocs\bridgoo\inc\register.php on line 24

6
  • if ($conn->connect_error) { you are inside ERROR flow ? or you are inside clean_input function? last one - you need to pass $conn as a param into this finction. Or you can do global $conn inside the function. But that is very bad practice I would say. Commented Feb 2, 2018 at 0:20
  • clean_input() get rid of that method; you're using a prepared statement, you don't need it. Now check for errors on the query mysqli_error($conn) then show us what the errors are, if any. Commented Feb 2, 2018 at 0:23
  • thats a typo - copied the db.php. not in the affected script Commented Feb 2, 2018 at 0:23
  • 1
    well you have another issue here, and nobody caught that except me heh - the variables and column names; they're not in their sequence. Commented Feb 2, 2018 at 1:17
  • 1
    Good catch @FunkFortyNiner . The whole code gave me the shivers, but spotting that alignment issue was a keen eye. Commented Feb 2, 2018 at 1:22

3 Answers 3

4

The error about undefined variable $conn has to do with PHP variable scope, and other people have answered that.

But your code needs some other suggestions too.

You don't need to clean inputs at all if you use query parameters. That's the point of using query parameters: No need for mysqli_real_escape_string() because parameters are automatically safe.

In fact, you must not use mysqli_real_escape_string(), because your data will be inserted to your database literally with \' escaped apostrophes.

Simply put: SQL parameters and mysqli_real_escape_string() are mutually exclusive. Don't do both.

Also, it makes no sense to use htmlentities() or htmlspecialchars () at all for sanitizing SQL inputs, even if you use mysqli_real_escape_string() instead of parameters.

Those html-related functions are for HTML output only. They're very important for protecting your web app against XSS vulnerabilities, which is another unrelated web security risk you need to know about. But they're not needed for sanitizing SQL input.

Other comments:

  • It's confusing that you're re-using username and password variables for both the mysqli connection and the application data. There's no reason to re-use variables, they don't cost you anything.
  • Make sure the order of parameters in your INSERT matches the order of bind variables you pass to bind_param().
  • Always check the return value of prepare() and execute(). They return FALSE if they fail. If they fail, you must log the error and report to the user that the page didn't work.

    I prefer to log the technical error message to the PHP error log file, and report something more friendly to the user.

    Get into the habit of keeping a window open to watch your PHP error log during development, it'll help you a lot.

Here's how I suggest you write your code:

<?php

$mysql_servername = "localhost";
$mysql_username = "root";
$mysql_password = "";
$mysql_dbname = "bridgoo";

$conn = new mysqli($mysql_servername, $mysql_username, $mysql_password, $mysql_dbname);

if ($conn->connect_error) {
  error_log($conn->connect_error);
  die("Sorry, a database error occurred.");
}

$stmt = $conn->prepare("
  INSERT INTO bridgoo_users (username, password, email) 
  VALUES (?, ?, ?)");
if ($stmt === false) {
  error_log($conn->error);
  die("Sorry, a database error occurred.");
}

$stmt->bind_param("sss", $username, $password_hash, $email);

//generate password hash using blowfish algorithm
$password_hash = password_hash($_POST['password'], PASSWORD_BCRYPT, ["cost" => 9]);

$username = $_POST['username'];
$email = $_POST['email'];

if ($stmt->execute() === false) {
  error_log($conn->error);
  die("Sorry, a database error occurred.");
}

if ($stmt->affected_rows == 1) {
  echo "Success!"
} else {
  echo "Sorry, an unknown problem occurred, and your record was not saved."
}
Sign up to request clarification or add additional context in comments.

4 Comments

Renaming the variables for the connection was also a good idea, since the OP is using the same variable for the password, which in fact could be an issue since one may be overwriting the other. That could also trigger an escape gate for an alleycat. ;-)
Hey wait a minute, the variables and column names are out of order. I just spotted that now. That'll fail on password_verify().
@FunkFortyNiner, thanks, good catch, I didn't notice that. I've fixed it in my example code, and added a note to my bullet list above.
You're welcome Bill. There stands to be other issues, but that remains to be known or said. Let's only hope they've stuck to the manual on everything ;-) Some things do tend to fail silently. Great answer btw.
-1

Your clean_input function does not have access to your $conn variable, it lives in a different scope.

The easy solution would be to add the connection as a parameter to the function. Something like this:

<?php
...


$username = clean_input($_POST['username'], $conn);
$password = clean_input($password_hash, $conn);
$email = clean_input($_POST['email'], $conn);


function clean_input($input, $conn){

...

Wether that is the best or cleanest solution I'll leave in the middle, but it should work just fine.

Comments

-1

You should pass $conn as parameter to your function clean_input;

$username = clean_input($conn, $_POST['username']);
$password = clean_input($conn, $password_hash);
$email = clean_input($conn, $_POST['email']);


function clean_input($conn, $input){

    $input = htmlentities($input);
    $input = htmlspecialchars($input,ENT_QUOTES);
    $input = mysqli_real_escape_string($conn,$input);

    return $input;
}

6 Comments

passing $conn as a parameter throws undefined function when its called
Fatal error: Call to undefined function clean_input() in C:\xampp\server1\htdocs\bridgoo\inc\register.php on line 13
i call it like clean_input($conn,$_POST['username']);
Post your php file. line 13 in the one you posted is // Check connection
POST YOUR FILE. There are no mentalists here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.