When trying to bind params i get the error: "Call to a member function bind_param() on a non-object in ....." These queries run fine on separate scripts but when i want to run them nested i keep getting the same error. I've tried a lot to find out how to fix it but could not.
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
$ignore_time=time()-(24*60*60);
$stmt=$mysqli->prepare("select id,new_count from view_gallery where lastUpdate< ? and new_count >0");
$stmt->bind_param('i',$ignore_time);
$stmt->execute();
$stmt->bind_result($id, $count);
while($stmt->fetch())
{
$stmt_new=$mysqli->prepare("update gallery set power=power + ? where id= ?");
$power=$count* 0.01;
$stmt_new->bind_param('di',$power,$id);
$stmt_new -> execute();
}
The error is thrown in the bind_param line inside the loop.
The error is because your prepare() call is not returning a valid object. This is accounted to the fact that your SQL query is wrong.
In your query, you have power which is a reserved function keyword in MySQL.
Escape it using backticks in the query and your code will work.
$stmt_new = $mysqli->prepare( "UPDATE gallery SET `power` = `power` + ? WHERE `id` = ?" );
Using backticks is always a good practice.
the solution was that the results of the outer loop were to be saved:
$stmt->store_result();
right above the while loop.
Related
I have the following query:
$query = <<<SQL
SELECT
year,
count(*) AS `counter`,
GROUP_CONCAT(team) AS `team_list`
FROM
team_list
WHERE year IS NOT NULL
SQL;
if (!empty($sql)) { //$sql is an array of SQL WHERE statements "a IN (a,b,c)"
$query .= ' AND ' . implode(' AND ', $sql);
}
$query .= 'GROUP BY year ORDER BY year';
/////////////////////////////
//EXECUTING THE QUERIES
/////////////////////////////
//Filter count to know how many 's' variable have to be bind to the prepared statement
$filterCount = count($teams) + count($countries) + count($years) + count($rankings); //These are my ajax elements that are also used in the $sql variable
//Data query
$queryYears = $connection->prepare($query);
$queryYears->bind_param(str_repeat('s', $filterCount), ...$teams, ...$countries, ...$years, ...$rankings);
$queryYears-> execute();
This all works very fine!
THE PROBLEM
However, once I try to enter SET SESSION group_concat_max_len = 1000000; at the beginning of my query statement I get the following error:
Fatal error: Uncaught Error: Call to a member function bind_param() on boolean
I understand that something is now wrong with my query, but when copy-pasting it to my DBMS the query can be executed without a problem.
What am I doing wrong here?
Your problem is that you are trying to execute two queries at once, and mysqli::prepare doesn't support that, so it fails and returns false. Instead, run the variable set as a separate query first:
$connection->query("SET SESSION group_concat_max_len = 1000000;") or die($connection->error);
$queryYears = $connection->prepare($query) or die($connection->error);
// etc.
Note that you should be checking the status of your calls, as I have done in the code above.
I have a little (and stupid) problem: I'm building a PHP application using mysqli and a MySQL server. When the application is loaded, a variable called $database is initialized using
$database = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
This, of course, works perfectly. If I create an statement to do a query:
$stmt = $database->prepare('SELECT a, b, c FROM table WHERE a = ?');
This still works. But, if I try to create another statement without closing the previous one, sometimes works, and sometimes now. The error I get when the creation of the statement fails is:
Fatal error: Call to a member function bind_param() on a non-object
And my question is: why? What should I do, open a connection (new mysql(...)) every time I want to create a new statement (and I have another open)?
Example
$stmt = $database->prepare('SELECT a, b, c FROM table WHERE a = ?');
$stmt->bind_param('i', $aValue);
$stmt->execute();
/* do some other operations, without closing $stmt */
$stmt2 = $database->prepare('INSERT INTO table2 (e, f) VALUES (? ,?)');
// Now, $stmt2 isn't initialized, so when the next line is run, the app fails
$stmt2->bind_param('ss', $someValue, $anotherValue);
If, before the
$stmt2 = $database->prepare('INSERT INTO table2 (e, f) VALUES (? ,?)');
I add a simple
$stmt->close();
All works without any problems. So, what is the problem?
You cannot run another query until you have fetched all the results from the previous. Otherwise you will have to make a separate connection.
Did you remember to bind_param & execute ? :
$stmt->bind_param("s", $string);
$stmt->execute();
//etc..
OR
$stmt->bind_param("i", $int);
$stmt->execute();
//etc..
IF you want multiple queries : check out multi_query
The current error when running this from the command line is "Call to a member function bindParam() on a non-object" which I've worked out to being a problem with the variable $orderPO. Something does not like non-numeric characters which led me to the bindParam PARAM_STR business which does not work either. The database fields are both varchar 50.
My search skills are failing me. I know this must be posted somewhere about a million times but I can't seem to find it. I am completely open to doing this another way if someone has a better idea.
Current attempt code:
try
{
$orderNum = '123456';
$orderPO = '123456-A';
$dbh = new PDO("mysql:host=localhost;dbname=dbname", 'someuser', 'somepass');
$stm = $dbh->prepare("insert into some_table (order_number, order_po)");
$stm->bindParam(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindParam(':order_po', $orderPO, PDO::PARAM_STR);
$stm->execute();
print_r($stm);
print_r($dbh);
$arr = $stm->errorInfo();
print_r($arr);
$stm->closeCursor();
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
In order to bind parameters using PDO, you will need to use placeholders, like this:
$stm = $dbh->prepare("
INSERT INTO `some_table` SET
`order_number` = :order_number,
`order_po` = :order_po
");
$stm->bindParam(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindParam(':order_po', $orderPO, PDO::PARAM_STR);
Notice the inclusion of the : character before the named placeholder. I also added column names to your query.
Read further and see examples: PDO bindParam
The correct syntax is
$stm = $dbh->prepare("insert into some_table (order_number, order_po) VALUES (?, ?)");
$stm->bindParam(1,$orderNum);
$stm->bindParam(2,$orderPO);
include the questions marks, the numbers in the bindParam call refer to which question mark you're binding the parameter to
You are trying to use bindparam, but bind param matches ? not cursors :. You have not included any parameters or values.
Also, you are missing your VALUES statement within the query, which is causing the query to fail. This is why you get the "Call to a member function bindParam() on a non-object"
To use the :value syntax, use bindValue, not bindParam. to use bindParam, switch the :value to ? in your query and number them in order is your execute array.
try
{
$orderNum = '123456';
$orderPO = '123456-A';
$dbh = new PDO("mysql:host=localhost;dbname=dbname", 'someuser', 'somepass');
$stm = $dbh->prepare("insert into some_table (order_number, order_po) VALUES (:order_number, :order_po)");
$stm->bindvalue(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindvalue(':order_po', $orderPO, PDO::PARAM_STR);
$stm->execute();
print_r($stm);
print_r($dbh);
$arr = $stm->errorInfo();
print_r($arr);
$stm->closeCursor();
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
I'm going through a video tutorial about doing a menu using a db. Instead of doing it with procedural PHP like in the video, I tried doing it with prepared statements OOP style. It doesn't work and I can't figure out why.
It runs fine until line 17, where it dies with this error:
Fatal error: Call to a member function bind_param() on a non-object in C:\wamp\www\widget_corp\content.php on line 17
And here's the code:
<?php
$query = $connection->prepare('SELECT menu_name, id FROM subjects ORDER BY position ASC;');
$query->execute();
$query->bind_result($menu_name, $sid);
while ($query->fetch()){
echo "<li>{$menu_name} {$sid}</li>";
$query2 = $connection->prepare('SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;');
$query2->bind_param("i", $sid); //This is line 17
$query2->execute();
$query2->bind_result($menu_name);
echo "<ul class='pages'>";
while ($query2->fetch()){
echo "<li>{$menu_name}</li>";
}
echo "</ul>";
}
$query->close();
?>
Is it impossible to do a prepared statement within stmt->fetch();?
Figured it out:
After executing and binding the result, it has to be stored (if another prepared statement is to be put in the fetch). So the fetching in this case has to be read from a buffered result.
In other words, can't execute another query until a fetch on the same connection is in progress.
The working code:
$query = $connection->prepare("SELECT menu_name, id FROM subjects ORDER BY position ASC;");
$query->execute();
$query->bind_result($menu_name, $sid);
$query->store_result();
$stmt = mysqli_prepare($con,"SELECT menu_name, id FROM subjects ORDER BY position ASC");
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $menu_name, $id);
while (mysqli_stmt_fetch($stmt))
{
$stmt2 = mysqli_prepare($con2,"SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;");
mysqli_stmt_bind_param($stmt2,$id);
mysqli_stmt_execute($stmt2);
mysqli_stmt_bind_result($stmt2, $name);
while (mysqli_stmt_fetch($stmt2))
echo $name;
}
look at the $con and $con2, you can not execute a prepare statement within another ps using the same connection !!!
Yes, you can have several prepared statements : one of the ideas of prepared statements is "prepare once, execute several times".
So, you should prepare the statement outside of the loop -- so it's prepared only once
And execute it, several times, insidde the loop.
The Fatal error you get means that $query2 on line 17, is not an object -- which means the prepare failed.
A prepare typically fails when there is an error in it ; are you sure your query is valid ? The tables and columns names are OK ?
You should be able to get an error message, when the prepare fails, using mysqli->error() -- or PDO::errorInfo()
You don't say what DB extension you are using but you don't seem to test the return value of any function you are using. You can't assume that DB calls will always run flawlessly.
I'm trying to learn to use PDO instead of MySQLi for database access and I'm having trouble selecting data from the database. I want to use:
$STH = $DBH->query('SELECT * FROM ratings WHERE title=$title ORDER BY date ASC');
$STH->setFetchMode(PDO::FETCH_ASSOC);
while($row = $STH->fetch()) {
echo $row['title'];
}
but I'm getting this error:
Fatal error: Call to a member function setFetchMode() on a
non-object in
/home/owencont/public_html/owenstest.com/ratemystudents/index.php
on line 6
If I take out the WHERE statement it works fine. How can I select a row based on if it's value matches a variable?
Thanks,
Owen
It's likely a SQL syntax error, because you forgot to quote $title. It ended up as bareword in the query (also not even interpolated as string), resulting in an error. And your PDO connection was not configured to report errors. Use ->quote() on arguments before the ->query():
$title = $DBH->quote($title);
$STH = $DBH->query("SELECT * FROM ratings WHERE title=$title ");
Or better yet, use parameterized SQL:
$STH = $DBH->prepare("SELECT * FROM ratings WHERE title=? ");
$STH->execute(array($title));
Take a look at PDO::prepare and PDOStatement::execute. The safest way to add user content to a query is to prepare a basic statement and bind the parameter to it. Example (note the question mark in the SQL statement):
$STH = $DBH->query('SELECT * FROM ratings WHERE title=? ORDER BY date ASC');
$STH->execute( array( $title ) );
while( $row = $STH->fetch( PDO::FETCH_ASSOC ) );
Make PDO throw errors so you can see what exactly goes wrong. See How to squeeze error message out of PDO?
You are probably missing quotes around $title but this scenario really calls for prepared statements instead.
remove the variable out of the sql statement because its a php variable
$STH = $DBH->query('SELECT * FROM ratings WHERE title=' . $title . 'ORDER BY date ASC');
Use double quotes instead of single quotes as a parameter of the query-method.
The reason you're getting this error is because the query-method fails and so the $STH object isn't created. You should implement some error handling.