Page 1 of 1

Help with MySQLi error please

Posted: Thu Mar 15, 2012 6:54 am
by bytephp
Hi,

I keep getting a number of errors and am struggling to fix. I've tried adding the database connection variable $connection or $cn as the $link within my mysqli_real_escape_string but no luck.

Errors
Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in C:\wamp\www\login-register\login\functions\functions.php on line 39

Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in C:\wamp\www\login-register\login\functions\functions.php on line 36

Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in C:\wamp\www\login-register\login\functions\functions.php on line 42

Catchable fatal error: Object of class mysqli could not be converted to string in C:\wamp\www\login-register\login\functions\user.php on line 18


functions.php

Code: Select all

function processLoginForm ($formData) {
	foreach ($formData as $key => $value) {
		switch ($key) {	
			case 'pword' : 
				$local[$key] = mysqli_real_escape_string(sha1(trim($value)));  // line 36
				break;
                        case 'uname' : 
				$local[$key] = mysqli_real_escape_string(strip_tags(trim($value))); // line 39 
				break;
			default : 
				$local[$key] = mysqli_real_escape_string(sanitiseInput($value)); // line 42
		}
	}
	return $local;
}

user.php

Code: Select all

function db_authUser($connection, $username = "", $password = "") {
	$sql = "SELECT id FROM users WHERE username = '$username' AND password = '$password'";   // line 18
	$result = mysqli_query($connection, $sql);	
	$numRows = mysqli_num_rows($result);
	if ($numRows == 1) {
		$row = mysqli_fetch_assoc($result);
		return $row['id'];	
	} else {
		return false;
	}
}
Thanks in advance.

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 7:00 am
by Celauran
Are these functions part of some class where the database connection is defined? Perhaps they should be. The first error is certainly because your database connection variable does not exist within that function's scope. You'd need to pass it in as a variable (bad) or use the global keyword (worse). The second error, with no additional context, will be tougher. That line by itself is fine.

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:08 am
by bytephp
Hi,

I tried passing it in as a variable, but no luck. Unless I did it incorrectly. Here is all the code below so should be easier to spot.

database.php

Code: Select all

<?php
// Database Connection Settings


// setting variable for db connection
$host = "localhost";
$username = "root";
$password = "";
$database = "myDatabase";

// connect to database
$connection = mysqli_connect("$host", "$username", "$password", "$database");
if (!$connection) {
    die("Could not connect: " . mysqli_error());
}

// Function list
//
// db_getRowById()
// db_allRowsAsTable()


function db_getRowById($tableName, $connection, $id = 0) {
	$sql = "SELECT * FROM $tableName WHERE id=$id";
	$result = mysqli_query($sql, $connection);
	return mysqli_fetch_assoc($result);
}



function db_allRowsAsTable($tableName, $connection) {
	$sql = "SELECT * FROM $tableName";
	$result = mysqli_query($sql, $connection);
	echo "<table>";
	while ($row = mysqli_fetch_assoc($result)) {
		echo "<tr>";		
		foreach ($row as $key=>$value) {
			echo "<td>" . $value . "</td>";
		}
		echo "</tr>";			
	}
	echo "</table>";
}

?>
functions.php

Code: Select all

<?php
// Always start a session
session_start();

// Bring in all the function files

require_once("database.php");
require_once("user.php");

//Always get a database connection
$cn = $connection;


// Function list
//
// processFormData()
// processLoginForm()
// sanitiseInput()
// setMessage()
// outputMessage()
// redirect()
// fillValue()


function processFormData ($formData) {
	foreach ($formData as $key => $value) {	
		$local[$key] = sanitiseInput($value);
	}
	return $local;
}

function processLoginForm ($formData) {
	foreach ($formData as $key => $value) {
		switch ($key) {	
			case 'pword' : 
				$local[$key] = mysqli_real_escape_string (sha1(trim(($value))));  // line 36
				break;
                        case 'uname' : 
				$local[$key] = mysqli_real_escape_string(strip_tags(trim($value))); // line 39 
				break;
			default : 
				$local[$key] = mysqli_real_escape_string(sanitiseInput($value)); // line 42
		}
	}
	return $local;
}

function sanitiseInput ($input="") {
	if (get_magic_quotes_gpc()) {
		$cleaned = htmlspecialchars(trim($input));
	} else {
		$cleaned = addslashes(htmlspecialchars(trim($input)));
	}
	return $cleaned;	
}



function setMessage ($message="") {
	if (isset($_SESSION['msg'])) {
		$_SESSION['msg'] .= $message . "<br/>";
	} else {
		$_SESSION['msg'] = $message . "<br/>";
	}

}

function outputMessage () {
	if (isset($_SESSION['msg'])) {
		echo "<p class='msg'>" . $_SESSION['msg'] . "</p>";
	}
	unset ($_SESSION['msg']);
}

function redirect ($url) {
	header("Location: $url");
	exit();
}

function fillValue($field) {
	if (isset($_SESSION['form'][$field])) {		//check if field info is set to be returned
		$data = $_SESSION['form'][$field];
		echo "value='$data' ";					//echo the HTML value attribute with data
		unset($_SESSION['form'][$field]);
	}	
}

?>
user.php

Code: Select all

<?php
// Function list
//
// db_authUser()
// processNewUserForm()
// userLoggedIn()
// db_userAdminTable()
// db_deleteUser()
// db_addUser()
// db_validateNewUser()
// usernameExists()
// db_getUserForm()
// db_updateUser()
// db_validateExistingUser()


function db_authUser($connection, $username = "", $password = "") {
	$sql = "SELECT id FROM users WHERE username = '$username' AND password = '$password'";   // line 18
	$result = mysqli_query($connection, $sql);	
	$numRows = mysqli_num_rows($result);
	if ($numRows == 1) {
		$row = mysqli_fetch_assoc($result);
		return $row['id'];	
	} else {
		return false;
	}
}

function processNewUserForm ($formData) {
	foreach ($formData as $key => $value) {
		switch ($key) {	
			case 'password' : 
				$local[$key] = sha1($value);
				break;
                        case 'username' : 
				$local[$key] = sanitiseInput($value);
				break;
			default : 
				$local[$key] = sanitiseInput($value);
		}
	}
	return $local;
}

function userLoggedIn($level=1) {
	if (isset($_SESSION['loggedin']) and $_SESSION['loggedin']) {
		//do an additional level check
		if ($_SESSION['level'] < $level) {
			return false;
		} else {
			return true;	
		}	
	} else {
		return false;
	}
}

function db_userAdminTable($connection) {
	$sql = "SELECT * FROM users";
	$result = mysqli_query($connection, $sql);
	echo "<table border=1>";
	$header = true;

	while ($row = mysqli_fetch_assoc($result)) {

		//do table headers from field names
		if ($header) {
			echo "<tr>";
			foreach ($row as $key=>$value) {
				echo "<th>" . $key . "</th>";
			}
			echo "</tr>";		
			$header = false;		
		}

		echo "<tr>";
		foreach ($row as $key=>$value) {
			echo "<td>" . $value . "</td>";
		}
		
		//add additional links for administering 
		echo "<td><a href='admin-users-edit-form.php?id=".$row['id']."'>edit</a></td>";
		echo "<td><a href='admin-users-delete.php?id=".$row['id']."'>delete</a></td>";
		
		echo "</tr>";
					
	}
	echo "</table>";
}

function db_deleteUser($id, $connection) {
	$sql = "DELETE FROM users WHERE id = $id";
	$result = mysqli_query($sql, $connection);
	if (mysqli_affected_rows() <> 1) {
		return false;	
	} else {
		return true;	
	}
}

function db_addUser($user, $connection) {
	
	foreach ($user as $key => $value) {
		$$key = $value;					//it is okay to use local variables within a function		
	}
	
	$sql = "INSERT INTO users (name, username, password, level) VALUES ('$name','$username','$password', $level)";
	$result = mysqli_query($sql, $connection);	
	$numRows = mysqli_affected_rows($connection);
	if ($numRows >= 1) {
		return true;	//user inserted
	} else {
		return false;	//user not inserted
	}	
}

function validateNewUser($person, $connection) {
	$error = false; 	//set a no error flag

	if (empty($person['name'])) {
		setMessage("Please supply a name for the user.");
		$error = true;
	}
	if (db_usernameExists($person['username'], $connection)) {
		setMessage("Sorry that username is already taken.");
		$error = true;
	}	
	if (!is_numeric($person['level'])) {
		setMessage("The user level should be a number.");
		$error = true;		
	}	
	
	if ($error) {  //if error has been set as true then do the following
		foreach ($person as $key => $value) {
			$_SESSION['form'][$key] = $value;   //populate a session variable with the oringal form data
		}
		return false;	
	} else {
		return true;	
	}

}

function db_usernameExists($username, $connection) {
	$sql = "SELECT id FROM users WHERE username = '$username'";
	$result = mysqli_query($sql, $connection);	
	$numRows = mysqli_num_rows($result);
	if ($numRows >= 1) {
		return true;	//username already exists in db
	} else {
		return false;	//username does not exist in db
	}	
}

function db_getUserForm($id, $connection) {
	$sql = "SELECT * FROM users WHERE id = $id";
	$result = mysqli_query($connection, $sql);	
	$numRows = mysqli_num_rows($result);		
	if ($numRows == 1) {		//check if field info is set to be returned
		$user = mysqli_fetch_assoc($result);
		foreach ($user as $key => $value) {
			$_SESSION['form'][$key] = $value;	
		}
	}	
}

function db_updateUser($user, $id, $connection) {
	
	foreach ($user as $key => $value) {
		$$key = $value;					//it is okay to use local variables within a function		
	}	
	$sql = "UPDATE  users SET name='$name', username='$username',password='$password',level=$level WHERE id=$id";
	$result = mysqli_query($sql, $connection);	
	$numRows = mysqli_affected_rows($connection);
	if ($numRows >= 1) {
		return true;	//user updated
	} else {
		return false;	//user not updated
	}	
}

function db_validateExistingUser($person) {
	$error = false; 	//set a no error flag

	if (empty($person['name'])) {
		setMessage("Please supply a name for the user.");
		$error = true;
	}
	
	if (!is_numeric($person['level'])) {
		setMessage("The user level should be a number.");
		$error = true;		
	}	
	
	if ($error) {  //if error has been set as true then do the following
		foreach ($person as $key => $value) {
			$_SESSION['form'][$key] = $value;   //populate a session variable with the oringal form data
		}
		return false;	
	} else {
		return true;	
	}

}

?>

do-login.php

Code: Select all

<?php
require_once("functions/functions.php");

if (!isset($_POST['submit'])) {
	redirect("login.php");	
}

$login = processLoginForm($_POST);


if ($uid == db_authUser($login['uname'], $login['pword'], $cn)) {

	$user = db_getRowById($uid, "users", $cn);

	$_SESSION['uid'] = $user['id'];
	$_SESSION['username'] = $user['username'];
	$_SESSION['level'] = $user['level'];
	$_SESSION['loggedin'] = true;
	redirect("admin.php");

} else {

	setMessage("Username or password incorrect");
	redirect("login.php");

}


?>

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:26 am
by Celauran
processFormLogin() still clearly does not have the SQL connection as an argument.

You could try this:

Code: Select all

function processLoginForm ($db, $formData) {
    foreach ($formData as $key => $value) {
        switch ($key) { 
            case 'pword' : 
                $local[$key] = mysqli_real_escape_string ($db, sha1(trim(($value))));  // line 36
                break;
            case 'uname' : 
                $local[$key] = mysqli_real_escape_string($db, strip_tags(trim($value))); // line 39 
                break;
            default : 
                $local[$key] = mysqli_real_escape_string($db, sanitiseInput($value)); // line 42
        }
    }
    return $local;
}
I still don't see anything wrong with db_AuthUser(). Maybe it's how it's being called that's the problem?

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:37 am
by bytephp
Thanks. Yeah I tried something like this before but no joy. Tried using how you did the code but ended up with the following errors.....

Warning: Missing argument 2 for processLoginForm(), called in C:\wamp\www\login-register\login\do-login.php on line 8 and defined in C:\wamp\www\login-register\login\functions\functions.php on line 32

Notice: Undefined variable: formData in C:\wamp\www\login-register\login\functions\functions.php on line 33

Warning: Invalid argument supplied for foreach() in C:\wamp\www\login-register\login\functions\functions.php on line 33

Notice: Undefined variable: local in C:\wamp\www\login-register\login\functions\functions.php on line 45

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:38 am
by Celauran
The function definition is only half of it. Did you adjust the function calls accordingly?

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:45 am
by bytephp
Not quite sure what you mean to do sorry or what/how to edit.

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:48 am
by Celauran
In do-login.php you have this:

Code: Select all

$login = processLoginForm($_POST);
If you change the function signature of processLoginForm() to this:

Code: Select all

function processLoginForm ($db, $formData) {
then you also have to update how you call the function like so:

Code: Select all

$login = processLoginForm($cn, $_POST);

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 8:53 am
by Celauran
I'm noticing the same sort of problem all over the place.

The function is defined as

Code: Select all

function db_authUser($connection, $username = "", $password = "") {
but called as

Code: Select all

$uid == db_authUser($login['uname'], $login['pword'], $cn)
It's the right arguments, but in the wrong order.

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 9:18 am
by bytephp
Thanks :D

So it is pretty much always a case of using the database connection variable first? Now I seem to be getting denied into my secure areas saying username or password incorrect. No error message from PHP displaying, guess it must still be the order of my variables? Not sure where though.

Re: Help with MySQLi error please

Posted: Thu Mar 15, 2012 9:27 am
by Celauran
bytephp wrote:So it is pretty much always a case of using the database connection variable first?
No. It's a case of the function call agreeing with the function signature. You need the right arguments in the right order, or results will be unexpected at best.
bytephp wrote:Now I seem to be getting denied into my secure areas saying username or password incorrect. No error message from PHP displaying, guess it must still be the order of my variables? Not sure where though.
If you look at do-login, you get that message when this fails:

Code: Select all

if ($uid == db_authUser($login['uname'], $login['pword'], $cn)) {
Check that the order of arguments matches. Try separating it into two lines:

Code: Select all

$uid = db_authUser($cn, $login['uname'], $login['pword']);
var_dump($uid); // This should help with debugging.
if ($uid) {
Of course, this assumes you've updated

Code: Select all

$login = processLoginForm($_POST);
to read

Code: Select all

$login = processLoginForm($cn, $_POST);