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
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();
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
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.
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.
$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();