mysqli php sql statement does not execute - php

I have the strangest problem and I can figure out what is happening. There are no error being displayed and I've var_dumped $stmt and for will just not return anything.
The test data that i am trying to retrieve is correct and when i try the statement manually through phpmyadmin it would perfectly so I'm stumped any ideas?
$sql = "SELECT UserID,Password FROM Account WHERE ProfileName = ? OR Email = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$username = strtolower($username);
$stmt->bind_param('ss', $username, $username);
$stmt->bind_result($userID, $dbPassword);
$stmt->execute();
$stmt->fetch();

The bind_result() call must be done after execute() not before.
Change to:
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
$stmt->fetch();
From the Manual:
Note that all columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
Also, you can narrow down the problem by checking if prepare() succeeded and then subsequently if there are any rows:
if($stmt = $conn->prepare($sql))
{
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
if($stmt->num_rows > 0)
{
$stmt->fetch();
}
else
{
echo 'Query succeeded, but no rows found!';
}
}
else
{
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
// use trigger_error() not echo in production, after development
}
If prepare() fails, it means there is a either a connection error, syntax error or missing table/field name in the query.

Related

Error: call to a member function bind_param() , when doing 2nd bind_param()

I got the error
Fatal error: Uncaught Error: Call to a member function bind_param() on boolean
on this line:
$stmt->bind_param("i", $r);
Is my query prepared correctly?
I checked the name of the table and columns and they are correct
$stmt = $conn->prepare("UPDATE db_control SET cve_usuario=? WHERE cve_control=1");
$stmt->bind_param("i", $r);
heres my whole code:
<?php
$servername = "localhost";
$username = "usuario";
$password = "usuario";
$database = "proyectofinal";
// Create connection
$conn = new mysqli($servername, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("SELECT cve_usuario FROM db_control");
if($stmt->execute())
{
$stmt->bind_result($r);
if($stmt->fetch()){
echo $r;
}
$r = $r + 1;
echo "<br>" . $r;
$stmt = $conn->prepare("UPDATE db_control SET cve_usuario=? WHERE cve_control=1");
$stmt->bind_param("i", $r);
if($stmt->execute())
{
/*do something*/
}
}
?>
From the documentation of mysqli::prepare:
Return Values
mysqli_prepare() returns a statement object or FALSE if an error occurred.
You should check that the prepare call succeeded with a strict check ($stmt !== FALSE), though a simple if ($stmt) works in this specific case also.
If you want to know what made your prepare call fail, you can check the error code / message:
$stmt = $conn->prepare("...");
if ($stmt) {
// bind parameters, execute statement, etc
} else {
echo "MySQLi error: " . $conn->error;
}
I solved it! Forgot to close the connection before preparing the 2nd query.
That do the trick! Thanks

PHP - MySQLi Prepared Statements

$name = $_GET['user'];
if(isset($_GET['user']) && strlen($_GET['user'])>0) {
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $db);
$stmt = $mysqli->prepare("SELECT username FROM users WHERE username=?");
$stmt->bind_param('s', $name);
$stmt->execute();
while($stmt->fetch()) {
if($stmt->num_rows == 0) {
header("Location: home?errormsg=notfound");
exit();
}
}
$stmt->store_result();
$stmt->close();
}
$mysqli->close();
So, the above code checks if $_GET['name'] exists in the database, and if it doesn't, to redirect to home?errormsg=notfound but it redirects the usernames which exists in the database to the link 'home?errormsg=notfound' as well. Can you suggest a way to solve this problem?
You have to call $stmt->store_result() before $stmt->num_rows.
And your $stmt->fetch() is not necessary, because you don't use the selected data.
If you call store_result() after num_rows it won't work.
Part of comment from manual page:
If you do not use mysqli_stmt_store_result( ), and immediatley call
this function after executing a prepared statement, this function will
usually return 0 as it has no way to know how many rows are in the
result set as the result set is not saved in memory yet.
So your code should look like this:
$name = $_GET['user'];
if(isset($_GET['user']) && strlen($_GET['user'])>0) {
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $db);
$stmt = $mysqli->prepare("SELECT username FROM users WHERE username=?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 0) {
header("Location: home?errormsg=notfound");
exit();
}
$stmt->close();
}
$mysqli->close();
I have not tried this but maybe it helps.
You are calling $stmt->store_result(); after $stmt->num_rows
Please try moving $stmt->store_result(); before $stmt->num_rows
Example. you can see here

Error that will not show itself

I'm trying to code a registration system for a system I am making. Currently, I am receiving a MySQL error that makes me want to tear my head out each and every time I see it.
function UserRegister($user,$pass,$email,$first,$last)
{
$sqlfirst = mysql_real_escape_string($first);
$sqllast = mysql_real_escape_string($last);
$sqluser = mysql_real_escape_string($user);
$hashpass = crypt($pass);
$sqlpass = mysql_real_escape_string($hashpass);
$sqlemail = mysql_real_escape_string($email);
$sql = "SELECT *
FROM planerentalusers
WHERE user = '$sqluser' ";
if($result = mysqli_query($GLOBALS['db'],$sql))
{
$rowcount=mysqli_num_rows($result);
if($rowcount == 1)
{
echo "ERROR: There is already an account with that username! Click <a href='/PHPCalTest/login.php>here </a>to login if this is you. Otherwise, go back and try a different username.";
}
else
{
$sql2 = "INSERT INTO planerentalusers (first,last,user,pass,email) VALUES ('$sqlfirst','$sqllast','$sqluser','$sqlpass','$sqlemail')";
$result2 = mysqli_query($GLOBALS['db'],$sql);
if($result2 == true)
{
return true;
}
else return false;
}
}
else return false;
mysqli_free_result($result);
}
Above is the function that throws the error.
there is no PHP stack trace that is being thrown, so here is what I pinpointed it to: the query is failing. But how, I do not understand. Perhaps someone can point me in the right direction.
That is not a direct answer to your question. It has been solved somewhere between the comment lines.
Now, you can streamline and secure your code if you will:
use prepared statements. It's only natural since you are already using mysqli_* extension. Parameters that you pass to the prepared INSERT statement will be properly escaped.
utilize INSERT IGNORE syntax and check for affected rows with affected_rows. That way you do all you need to do hitting your database only once.
For INSERT IGNORE to work properly you have to have a UNIQUE constraint on username column.
ALTER TABLE planerentalusers ADD UNIQUE (username);
Now if you issue an INSERT IGNORE statement and a username doesn't exist a row will be inserted and affected_rows will return 1. If a username already exists then IGNORE clause will allow your INSERT statement to complete without throwing an error and affected_rows will return 0.
That being said an improved version of your function might look like
function UserRegister($db, $username, $pass, $email, $first, $last) {
$sql = "INSERT IGNORE INTO planerentalusers (first, last, username, pass, email) VALUES (?, ?, ?, ?, ?)";
// prepare the statement
$stmt = $db->prepare($sql);
if (!$stmt) {
die('Can\'t prepare: ' . $db->error); //TODO better error handling
}
// bind parameters
$stmt->bind_param('sssss', $first, $last, $username, $pass, $email);
if (!$stmt) {
die('Can\'t bind parameters: ' . $db->error); //TODO better error handling
}
// execute
$stmt->execute();
if (!$stmt) {
die('Query execution failed: ' . $db->error); //TODO better error handling
}
// get the number of affected rows
$affected_rows = $stmt->affected_rows;
// close the statement
$stmt->close();
return $affected_rows;
}
and the calling code
$first = $_POST['first'];
$last = $_POST['last'];
$username = $_POST['username'];
$pass = crypt($_POST['pass']);
$email = $_POST['email'];
//create a connection to the database
$db = new mysqli('localhost', 'user', 'password', 'dbname');
if ($db->connect_errno) {
die('Connection failed: ' . $db->connect_error); //TODO better error handling
}
if (!UserRegister($db, $username, $pass, $email, $first, $last)) {
echo "ERROR: There is already an account with that username! Click <a href='/PHPCalTest/login.php'>here </a>to login if this is you. Otherwise, go back and try a different username.";
} else {
echo "Account successfully created";
}
Note that
A reference to an open db connection is explicitly passed to the function instead of using $_GLOBALS['db']
presentation logic (echoing an error message and a link) is moved out to the calling code
Basic error handling is implemented throughout the function

Issue inserting data using mysqli in MySQL

I try to use mysqli in order to insert data in my database. But does not work. Where may be the error?
$myDb = new mysqli($hostname, $username, $password, $database);
if($myDb->connect_errno > 0){
die('Unable to connect to database [' . $myDb->connect_error . ']');
}
$statment = $myDb->prepare("INSERT INTO user(name,surname,age)
VALUES (?,?,?)");
$statement->bind_param('s', $_POST['name']);
$statement->bind_param('s', $_POST['surname']);
$statement->bind_param('i', 25);
$statement->execute();
$statement->free_result();
EDIT:
I obtain this error:
Binding parameters failed: (0) Execute failed: (2031) No data supplied for parameters in prepared statement
You've got the error here:
$statement->bind_param('i', 25);
25 is not a variable. You can only use variables when binding parameters. You can't use constants nor fixed strings or numbers when binding.
Besides, it never worked for me to split the parameters when binding. I got an error. I need to do so:
$myDb = new mysqli($hostname, $username, $password, $database);
if($myDb->connect_errno > 0){
die('Unable to connect to database [' . $myDb->connect_error . ']');
}
$statement = $myDb->prepare("INSERT INTO user (name,surname,age) VALUES (?,?,25)");
$statement->bind_param('ss', $_POST['name'], $_POST['surname']);
$statement->execute();
$statement->free_result();
$statement->close();
I solved the problem using a correct bind of parameter. Here the correct code:
$myDb = new mysqli($hostname, $username, $password, $database);
if($myDb->connect_errno > 0){
die('Unable to connect to database [' . $myDb->connect_error . ']');
}
$statment = $myDb->prepare("INSERT INTO user(name,surname,age)
VALUES (?,?,?)");
$statement->bind_param('s', $name);
$statement->bind_param('s', $surname);
$statement->bind_param('i', $age);
$name = $_POST['name'];
$surname = $_POST['surname'];
$age = 25;
$statement->execute();
$statement->free_result();

Passing mysqli connection to a PHP function - out of synch

I have a problem when performing mysql commands when I invoke a function in another file. If I have the code in the same file, it works fine. The code looks like:
authenticate:
{
$conn = new mysqli($dbserver, "dbuser", "pass", $dbname);
$sql = 'SELECT userId, salt, pwd, isAdmin FROM users where username = ?';
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('s', $username);
$stmt->bind_result($userId, $salt, $storedPwd, $isAdmin);
$stmt->execute();
$stmt->fetch();
}
Now, if I call a function, immediately after fetch, it fails on the bind_param line. I call it like this:
updateUserActivity ($conn, $tpcLang, 'LI', $userId);
the beginning of this function is:
function updateUserActivity ($conn, $lang, $activityType, $userId)
{
// check that activity is valid
$sql = 'SELECT activityType
FROM activityType
WHERE activityType = ?';
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('s', $activityType);
$stmt->bind_result($activityTypeInDB);
$stmt->execute();
$stmt->fetch();
if ($activityType == $activityTypeInDB){
$success=1;
} else {
$success=0;
$msg = $lang->get('UPDATE_USER_INVALID_ACTIVITY_ERROR_MSG') . " " . $activityType . " (" . $stmt->errno . "): " . $stmt->error;
error_log ($msg);
}
// continue on to add a row in the userActivity table
}
The error I get on the bind_param is: invalid object or resource mysqli_stmt, and the DB error is: Commands out of sync; you can't run this command now.
Any suggestions would be greatly appreciated.
try adding this after your fetch.
mysqli_free_result($result);
or
mysqli_close($conn);

Categories