Can't execute second MYSQLI query in same PHP file - php

Here is my code
$stmt = $mysqli->prepare("SELECT * FROM `accountsToDo` WHERE `OKrname` = ?");
$stmt->bind_param("s", $OKCUsername);
/* execute prepared statement */
$stmt->execute();
if ($stmt->affected_rows > 0){
echo "Exists";
} else {
$stmt = $mysqli->prepare("INSERT INTO `accountsToDo`(`percentageOfMessages`, `RemoveDeletedAccounts`, `RemoveNoReply`, `RemoveNoResponse`, `minMatchPercent`, `minDistance`, `maxDistance`, `blacklistUsernames`, `userEmail`, `OKrname`, `OKword`) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
$stmt->bind_param("iiiiiiissss", $percentageOfMessages, $RemoveDeletedAccounts, $RemoveNoReply, $RemoveNoResponse, $minMatchPercent, $minDistance, $maxDistance, $blacklistUsernames, $userEmail, $OKrname, $OKword);
$stmt->execute();
}
/* close statement and connection */
$stmt->close();
/* close connection */
$mysqli->close();
But now I'm getting the error,
Call to a member function bind_param() on boolean in line 147.
Line 147 is
$stmt->bind_param("iiiiiiissss", $percentageOfMessages, $RemoveDeletedAccounts, $RemoveNoReply, $RemoveNoResponse, $minMatchPercent, $minDistance, $maxDistance, $blacklistUsernames, $userEmail, $OKrname, $OKword);

If all you are doing is inserting into a todo table if the master table doesn't have a matching row, you don't need two statements.
INSERT INTO `accountsToDo`
(`percentageOfMessages`, `RemoveDeletedAccounts`,
`RemoveNoReply`, `RemoveNoResponse`, `minMatchPercent`,
`minDistance`, `maxDistance`, `blacklistUsernames`,
`userEmail`, `OKrname`, `OKword`)
VALUES (?,?,?,?,?,?,?,?,?,?,?)
WHERE NOT EXISTS (SELECT 1 FROM `accountsToDo` WHERE `OKrname` = ?);
Bind your params and you have save a call to the db. This has the advantage that "SELECT 1" acts as a cut operator so it is only evaluated until it finds the first TRUE.

You are missing a space between table name and a list of fields in your $mysqli->prepare
Try this:
$stmt = $mysqli->prepare("INSERT INTO `accountsToDo`
(`percentageOfMessages`,`RemoveDeletedAccounts`,
`RemoveNoReply`, `RemoveNoResponse`,
`minMatchPercent`, `minDistance`,
`maxDistance`, `blacklistUsernames`,
`userEmail`, `OKrname`, `OKword`)
VALUES (?,?,?,?,?,?,?,?,?,?,?)");
According to manual $mysqli->prepare will return FALSE if statement caused an error
UPDATE
Looks like your $mysqli->prepare is expecting 11 variables and you are trying to bind 12

The issue was that I didn't have
$stmt->store_result();
above the first $stmt->execute();

Related

PHP insert not working when using the ' symbol

I'm trying to insert some text into my database using mysqli trough PHP.
My insert statement is as follows:
$userID="1";
$description="Hi! It's been a while..."; //For example...
$sql = "INSERT INTO projecten (user_ref, description)
VALUES ('$userID','$description')";
if ($conn->query($sql) === TRUE) {
//redirect to right page
} else {
//error message...
}
The problem:
I always get an error message saying that there is something not right in my sql syntax near " 'ts been " Now I tried removing the ' symbol and then the code works, but I need to be able to let my users type what they want to type...
Does somebody know what I can do about this?
Thanks in advance!
Use bind_param It will handle all those string and prevent you form sql injection
$userID = "1";
$description = "Hi! It's been a while..."; //For example...
$stmt = $conn->prepare("INSERT INTO projecten (`user_ref`, `description`) VALUES (?, ?)");
$stmt->bind_param('is', $userID, $description);
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();

Mysqli bind_param error

I have a issue with my prepared statement, I have searched through stack for the answer and tried many off them them to no avail, I have check the insert statement which is correct, I have also tried using the statement as a regular statement which seems to work,
The error I get is as below
Fatal error:call to function bind_param()on a non object in ** on line 23
When I use a normal query on the first query the second does not show the error
The code is
public function reg_user($name,$username,$password,$email){
$password = password_hash($password);
$stmt = $this->db->prepare("SELECT uid FROM users WHERE uname= ? OR uemail = ?");
$stmt->bind_param("ss", $username,$email);
$stmt->execute();
$count_row = $stmt->num_rows;
if($count_row == 0){
$stmt = $this->db->prepare("INSERT INTO users (uname,upass,fullname,uemail) VALUES(?,?,?,?)");
$stmt->bind_param("ssss", $username,$password,$name,$email); //line 23
$return = $stmt->execute();
return $return;
} else{
return false;
}
}
Add these two lines of code after the first $stmt->execute
$result = $stmt->get_result();
$count_row = $result->num_rows;
The reason why your code fails is because you are trying to get the number of rows from a Prepared Statement object instead of a Result

Can I redefine the same prepared statement?

I have a script that sends more than 10 queries of all CRUD types on 5 tables (some of the SELECTs with JOINs). Originally, I used mysqli_* functions for all those. Now, to improve security, I am porting the code to use prepared statements.
I have no previous experience using prepared statements and I have some doubts about what can and cannot be done. For instance lets say I start by a SELECT query, then have an UPDATE and finally an INSERT.
My question is this:
Should I repeat the mysqli_stmt_init and mysqli_stmt_close for each query, or could I initiate once before the first query, prepare a statement for each query and use it and finally close it after all queries are done with? In other words, is method 2 OK, or should I stick to method 1?
Method 1 - No reuse
// SELECT
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "SELECT on table 1 and table 2");
...
mysqli_stmt_close($stmt);
// UPDATE
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "UPDATE on table 3");
...
mysqli_stmt_close($stmt);
// INSERT
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "INSERT INTO table 4");
...
mysqli_stmt_close($stmt);
Method 2 - Reusing statement
// INIT
$stmt = mysqli_stmt_init($link);
// SELECT
mysqli_stmt_prepare($stmt, "SELECT on table 1 and table 2");
...
// UPDATE
mysqli_stmt_prepare($stmt, "UPDATE on table 3");
...
// INSERT
mysqli_stmt_prepare($stmt, "INSERT INTO table 4");
...
// CLOSE
mysqli_stmt_close($stmt);
There is no need for stmt_init() or stmt_close(), mysqli_prepare() returns a stmt object and PHP handles the cleaning, the correct order is mysqli_stmt::prepare => mysqli_stmt::bind_param => mysqli_stmt::execute.
$mysqli = new mysqli( "host", "user", "pass", "db" );
$stmt = $mysqli->prepare( "SELECT * FROM table WHERE id = ?" );
$stmt->bind_param( "i", $id );
$id = 5;
$stmt->execute();
You can execute the same statement multiple times with different params, for example:
$stmt = $mysqli->prepare( "SELECT * FROM table WHERE id = ?" );
$stmt->bind_param( "i", $id );
$id = 5;
$stmt->execute(); // executed: SELECT * FROM table WHERE id = 5
$id = 3;
$stmt->execute(); // executed: SELECT * FROM table WHERE id = 3
But in case of different statements you must prepare each statement separately.
Yes, method 2 is ok.
There is no need to finally close it either, as it will be closed when your script ends.

MySQLi failing to prepare a statement

I'm running two queries in my script room.php. Both are using MySQLi prepared statements, and their code are as follows:
/* Get room name */
$stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?');
$stmt->bind_param('i', $roomID);
$stmt->execute();
$stmt->bind_result($roomName)
/* Add this user to the room */
$stmt = $mysqli->prepare('INSERT INTO `room_users` (r_id, u_id) VALUES (?, ?)');
$stmt->bind_param('ii', $roomID, $_SESSION['userID']);
$stmt->execute();
When I run the script, I get this error:
Fatal error: Call to a member function bind_param() on a non-object in C:\wamp\www\room.php on line 24
Which is the second query. If I remove the first query from the script, everything runs fine. Likewise if I remove the second query. Which leads me to believe there's a problem because I'm reusing the $stmt object. If I try the second query using $stmt2 I still get the error.
All my database tables and fields exist, so there's nothing wrong with the queries.
All of the mysqli functions/methods can fail in which case they will return false. I.e. if prepare() fails $stmt isn't an object you can call a method on but a bool(false). You have to check the return values and add some error handling, e.g.
$stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?');
if ( !$stmt ) {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
die;
}
$b = $stmt->bind_param('i', $roomID);
if ( !$b ) {
printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}
$b = $stmt->execute();
if ( !$b ) {
and so on and on
see http://docs.php.net/mysqli-stmt.errno et al
in this case you probably bumped into the problem that you can't create an other statement while there are still results/result sets pending for the previous statement.
see http://docs.php.net/mysqli-stmt.close:
Closes a prepared statement. mysqli_stmt_close() also deallocates the statement handle. If the current statement has pending or unread results, this function cancels them so that the next query can be executed.

Calling method from a non-object?

$query = "INSERT INTO users (name, password) VALUES ('$myusername', '$mypassword')";
if (!($result = $mysqli->query($query)))
die("WHAT???? " . $mysqli->error . " EEEEEFFFFFFF.");
$count = $result->num_rows;
while ($row = $result->fetch_array()) {
if ($row[name] == $myusername) {
$mysqli->query("DELETE FROM users WHERE name='$myusername' AND password='$mypassword'");
$count = 5;
}
}
When I run this, it gives me an error:
Fatal error: Call to a member function fetch_array() on a non-object in /home/appstore/public_html/phpstoof/signedup.php on line 26
Where line 26 is where the while statement starts (while(x)). $mysqli ALREADY an instance of mysqli(). I don't see the how this is an error if the same code works on another file.
An INSERT statement has nothing to fetch.
As #mellamokb says, INSERT has nothing to fetch. Also you have used a mix of MySQL and MySQLi.
With MySQLi, the code should be like:
$mysqli = new mysqli($db_host, $db_username, $db_password, $db_database);
$str_sql = 'INSERT INTO users (name, password) VALUES (?, ?)';
// Create a prepared statement
$stmt = $mysqli->prepare($str_sql);
// Bind parameters for markers; same order and same count in prepared statement
$stmt->bind_param('ss', $myusername, $mypassword);
// Execute query
$stmt->execute();
// *************************************************************************
// If you're using a SELECT statement, each output field must be bound to
// a variable in the same order as in SELECT
// Bind result variables
$stmt->bind_result($_var1, $_var2, $_var3, ...);
// Fetch results and generate output as an associative array
while ($stmt->fetch())
{
// Handle $_var1, $_var2, $_var3, ...
}
// *************************************************************************
// Free stored result memory
$stmt->free_result();
// Close statement
$stmt->close();
// Close connection
$mysqli->close();

Categories