MySQLi Prepared Statement not working in WHILE Loop - php

I'm working on a query inside a While loop. However, the Second run is not working. (The While is ended later, after some results get echoed). I've tried calling the second query $stma, however this resulted in the same error.
Error
Fatal error: Call to a member function bind_param() on a non-object in PATH on line 96
Code
// Prepare Query
$stmt = $db->prepare("SELECT id, fullname, shortname FROM languages WHERE (state = '0')");
$stmt->execute();
// Get result from query.
$stmt->bind_result($lang_id, $lang_name, $lang_short);
// While Loop
while($language = $stmt->fetch()){
// Get Language Texts
$stmt = $db->prepare("SELECT id, article_id, article_language, article_text, article_recuse, article_spec FROM article_content WHERE article_id = ? AND article_language = ?");
$stmt->bind_param("is", $artikel_nummer, $lang_short); // This is line 96.
$stmt->execute();
// Get result from query.
$stmt->bind_result($t_id, $t_articleid, $t_language, $t_text, $t_recuse, $t_spec);
$stmt->fetch();
I'm fairly new to prepared statements, so I'm not sure what exactly the problem is. I've ran a var_dump() on the query and it returned false, however, running the query elsewhere or outside the WHILE loop is working (When I Define the two variables by hand).
I've echoed $artikel_nummer and $lang_short, and it returns their values.
The question is the following: Why is the second query not running, and thus returning the error as stated above?

In your loop, you are overriding your $stm variable which holds a reference to your initial prepared statement (and indeed is the condition of your loop). For all queries happening inside loop, you must choose a different variable name:
while($language = $stmt->fetch()){
// Get Language Texts
$_stmt = $db->prepare("SELECT id, article_id, article_language, article_text, article_recuse, article_spec FROM article_content WHERE article_id = ? AND article_language = ?");
$_stmt->bind_param("is", $artikel_nummer, $lang_short); // This is line 96.
$_stmt->execute();
// Get result from query.
$_stmt->bind_result($t_id, $t_articleid, $t_language, $t_text, $t_recuse, $t_spec);
$_stmt->fetch();
}

Related

PHP MySQL Query don't deliver multidimensional Array

SOLVED: Reason Can I parameterize the table name in a prepared statement?
I have a very simple Query to collect data from a two column table in MySQL. Normally it worked but for some reason I know receive the error: Undefined offset: 1
$query_select = ("SELECT ?, ? FROM _HOOFDRUBRIEK");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("ss", $column1, $column2);
$stmt->execute();
$stmt->store_result();
//$count = $stmt->num_rows;
//echo $count;
/die();
$stmt->bind_result( $key_hoofdrubriek ,
$descr_hoofdrubriek );
$stmt->fetch();
$hoofdrubriek[] = array('key' =>$key_hoofdrubriek ,
'descr' =>$descr_hoofdrubriek );
//Here I request the variable, what occurs the error
$var = $hoofdrubriek[1]['descr'];
echo 'Show here what's in the var: '.$var ;
Does anyone know why I get this error, because from my point of view, a multidimensional array can be called by $array_name[row][column];
You are mistinpreting how that works. Result bind parameters are just bound in order to the selected field. You still need to select normal fields as usual.
Moreover, you cannot specify field names as input parameters. In your situation, you select two constant values, namely the strings you pass as input parameters. This is why you get the field names in the result instead of the values of those fields. The parameters are just string values, so the query that is executed would look like this:
SELECT 'key_hoofdrubriek', 'descr_hoofdrubriek' FROM FROM RGS_HOOFDRUBRIEK
So, skip the question marks and the input bind parameters altogether and build the query like so:
$query_select = ("SELECT key_hoofdrubriek, descr_hoofdrubriek FROM RGS_HOOFDRUBRIEK");
Or, if you must, by using PHP variables in the statement:
$query_select = ("SELECT $column1, $column2 FROM RGS_HOOFDRUBRIEK");
For reading, you can of course still use bind_result.
You can't use placeholders for column names, they're always treated as expressions. So your prepared query is equivalent to writing:
SELECT 'key_hoofdrubriek', 'descr_hoofdrubriek' FROM RGS_HOOFDRUBIEK
This just returns those literal strings for each row in the table, not the values in the columns with those names.
If you need to determine the column names dynamically, you have to use variable substitution or concatenation, you can't use placeholders:
$query_select = "SELECT $column1, $column2 FROM RGS_HOOFDRUBRIEK";

MySQL error: 'invalid use of a group function' [duplicate]

This question already has answers here:
Call to a member function bind_param() on a non-object [duplicate]
(6 answers)
Closed 7 years ago.
I have a referral application where an ID can only have 2 direct referrals. I am trying to find IDs which appear less than 2 times in the ID_REF field with the code below.
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
$stmt->bind_param("s", $n);
$n = 2;
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
$stmt->bind_result($id);
//$stmt->fetch();
$stmt->close();
//echo $id.' '.'oi';
while ($stmt->fetch()) {
echo $id;
}
You aren't checking for any errors, that is completely bad development. You should start by ensuring that your prepare() is actually preparing the query correctly and not failing...
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
// now check
if(!$stmt) {
die($conex->error); // or mysqli_error($conex);
} else {
$stmt->bind_param('s', $n);
}
Back to other matters. You seem to be trying to compare count(id_ref) which would be a number (int) against $n (which is an int too) but you're trying to pass it as a string.....?
You'll need to change that bind of yours to something like:
$stmt->bind_param('i', $n);
Also note, you can't set the $n variable after you call it.... that's going to throw an error.
Do the following:
var_dump($conex);
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
var_dump($stmt)
This should shed some light on the matter.
I'm betting the $stmt variable is bool or null.
Your code isn't checking whether prepare returned successfully.
If the prepare encounters an error, it returns FALSE. instead of a statement object.
And a boolean FALSE value (the return from prepare) does not have a method/function bind_param.
$stmt = $conex->prepare("...");
if(!$stmt) {
echo "error in prepare ". mysqli_error($conex) ;
} else {
// prepare returned a statement object so we can do a bind_param
$stmt->bind_param(...);
To fix a syntax issue in the SQL statement that's causing an error in prepare, replace they keyword WHERE with keyword HAVING.
The predicates (conditions) in the WHERE clause are evaluated when rows are accessed. So the result of an aggregate function (e.g. COUNT() is not going to be available at the time those conditions in the WHERE are check. There's no way for that condition to be evaluated until after the rows are accessed, and the aggregate functions are evaluated. Predicates (conditions) in the HAVING clause get evaluated later, so it's valid to reference aggregates in a HAVING clause.
Just making that change to the SQL statement isn't likely going to get you the result you are looking for. Without a specification, we're just guessing what you are trying to return.

Retrieving a value from mysqli query, and assigning it to a php variable

I am getting the ID of the last row inserted into the mysql database.
I want to fetch the ID and assign to a php variable I can use else where in the script.
I would prefer the most versatile method of doing this. So something along the lines of a mysqli_fetch_all (BOTH).
I can't seem to do this without while looping the results. Is there a cleaner way?
$query = "SELECT ID FROM Title
ORDER BY ID DESC
LIMIT 1";
$stmt = $conn->prepare($query);
$stmt->execute();
//Get the result and bind it to a php variable that can be used
//in another part of the script
//free result
//?
//close statement
$stmt->close();

Add up all rows where value is equal to ID

I've been looking up around for a couple tutorials of this and I've seemed out of luck. Basically, I have a database containing a winner's user ID (corresponding to the winners user ID) and a loser's ID. I am trying to create a members profile where it counts up all the rows the member has won. Here is what I have came up with:
$web = mysqli_query("select SUM(matches) WHERE WinnerUID='".$req_user_info['id']."'");
$web_sum=mysqli_fetch_assoc($web);
echo $web_sum;
Unfortunately, it doesn't display any number. Can anyone help?
I think you're looking for COUNT() not SUM(). And you didn't include a table name. Also remember that mysqli_fetch_assoc() returns the row as an array, it doesn't return the first column's value. Also, mysqli_query() requires the connection as the first argument.
$web = mysqli_query($conn, "select COUNT(*) as total FROM matches WHERE WinnerUID='".(int)$req_user_info['id']."'");
$row = mysqli_fetch_assoc($web);
echo $row['total'];
Don't concatenate variables into your SQL. Use a Prepared Statement with bound parameters. I have casted your ID as an (int) in the above code, which is a quick fix but you should switch to a Prepared Statement.
Prepared Statement example (object oriented interface instead of procedural):
if ($stmt = $conn->prepare("select COUNT(*) from matches WHERE WinnerUID = ?")) {
$stmt->bind_param("i", $req_user_info['id']);
$stmt->execute();
$stmt->bind_result($web_sum);
$stmt->fetch();
echo $web_sum;
$stmt->close();
}

What does this SQL statement do?

I am trying to understand this SQL statements :
$id = 5;
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
$stmt->execute(array('id' => $id));
while($row = $stmt->fetch()) {
print_r($row);
}
Can someone please explain me step by step what exactly is going on here?
From what i understand :
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
1) $stmt is about to take as iinput an SQL query. The SQL query is to select all the rows from a table that their id is equal to 5.
$stmt->execute(array('id' => $id));
2) We execute the statement. Now the $stmt has these rows?
$row = $stmt->fetch()
3) This is the most confusing line for me. What exactly happens here? Variable "row" takes one by one the rows that have id = 5 ? Is that what fetch() does ? And if yes , how exaxtly does it return the results? Its an array of all the correct answers? EG all the rows that have id = 5 ? I dont understand how exactly this while loop works here.The first time it runs "row" will have the first row ? The second time it runs , will have the second row that satisfies our creteria (id = 5) and so on? Is it like that every time i run fetch one result will be returned? And next time i run fetch , the next result , till there is no more result to satisfy the query?
I thing i am so close to get this one. Anything that could help me understand it completely would be highly appreciated !
I'll explain as comments:
$id = 5;
// Create a prepared statement - don't actually execute the statement yet.
// The :id value in the statement will be replaced by a parameter value (safely) when the
// statement is executed
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
// Execute the statement against the DB - the $stmt var now contains the result set for the
// executed statement. e.g. it contains *all* the results that the query fetched
$stmt->execute(array('id' => $id));
// Now we loop through the rows in the result set (they are all in memory at this point).
// "fetch" will start from row 1 and return the next result each time you call it again.
// when there are no more rows it returns FALSE and therefore breaks out of the while loop
while($row = $stmt->fetch()) {
print_r($row);
}
Just checking docs also and whilst this is how it was done previously (been years since I've touched PHP) it looks like stmt->fetch() actually places results into bound variables:
http://php.net/manual/en/mysqli-stmt.fetch.php
$row = array();
stmt_bind_assoc($stmt, $row);
// loop through all result rows
while ($stmt->fetch())
{
print_r($row);
}
Does the code you originally posted actually work? It doesn't appear you bind any variables and therefore since the $stmt-fetch() call returns bool TRUE/FALSE it would seem to be that $row would not get set to anything but TRUE/FALSE
here it uses PDO for execution,
Repeated SELECT using prepared statements through which you can call repeated query
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
it defines the prepared statement where :id is placeholder
$stmt->execute(array('id' => $id));
this places assigns the value to placeholder and execute the query
$row = $stmt->fetch()
it fetch the record from select
for more reference visit the link
http://www.php.net/manual/en/pdo.prepared-statements.php

Categories