I have the following code which was working until recently but is now giving an error. (I suspect my website host may have moved me to a new server or upgraded something without letting me know - again!)
function SqlPrepareAndExecute() {
global $mysqli;
// get the function parameters
$args=func_get_args();
// get the sql, and remove from the list
$sql=array_shift($args);
// prepare the statement
if ($stmt = $mysqli->prepare($sql)) {
// need to do some clever reflection stuff to call bind_param
$ref = new ReflectionClass('mysqli_stmt');
$method = $ref->getMethod("bind_param");
if($method->invokeArgs($stmt,$args))
// execute the statement
if ($stmt->execute())
// it worked!
return true;
else
$Error="Failed to execute prepared query";
else
$Error="Failed to bind query parameters";
}
else
$Error="Failed to prepare query";
error_log("SqlPrepareAndExecute " . $Error . "\n");
error_log("Error #" . $mysqli->errno . "\n" . $mysqli->error,0);
return false;
}
called like this:
if (SqlPrepareAndExecute($sql,'ssssi',$_POST[' etc...
Error:
PHP Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in ...
PHP Fatal error: Uncaught exception 'ReflectionException' with message 'Invocation of method mysqli_stmt::bind_param() failed' in ...
php version is 5.6.33
Any suggestions on how to fix this?
php 5.6 now has ... operator. So this can be simplified as follows:
function SqlPrepareAndExecute($sql, $types, ...$params) {
global $mysqli;
// prepare the statement
if ($stmt = $mysqli->prepare($sql)) {
// bind the parameters
if ($stmt->bind_param($types, ...$params))
// execute the statement
if ($stmt->execute())
// it worked!
return true;
else
$Error="Failed to execute prepared query";
else
$Error="Failed to bind query parameters";
}
else
$Error="Failed to prepare query";
error_log("SqlPrepareAndExecute " . $Error . "\n");
error_log("Error #" . $mysqli->errno . "\n" . $mysqli->error,0);
return false;
}
Related
I am trying to write a function for a prepared statement but when I run the code it's giving me an error:
mysqli_stmt_store_result() expects parameter 1 to be mysqli_stmt, null given
My function looks as follows:
function fn_preparedStatement($query, $types, $values){
global $dbconnection;
if (!$dbconnection) {
die("Function wm_dynamicForm connection failed.</br>");
}
$db = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($db, $query )) {
mysqli_stmt_bind_param($db, $types, ...$values);
if (!mysqli_stmt_execute($db)) {
echo "Execute Error: " . mysqli_error($dbconnection);
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
}
Then in my code I have:
$query = "SELECT * FROM Contacts WHERE First_Name = ?";
$types = "s";
$values = array("Mike");
fn_preparedStatement($query, $types, $values);
mysqli_stmt_store_result($db); //im getting the error on this line - null
So im thinking my issue is a scope issue. I am not sure what to "return" out of my function to make this work. When i write the code inline it works fine. It's when I move the prepared statement to a function and replace the inline code with the function im now getting error. Can someone please tell me where im messing up? Thank you so much.
You need to return the statement handle from the function
function fn_preparedStatement($query, $types, $values){
global $dbconnection;
if (!$dbconnection) {
die("Function wm_dynamicForm connection failed.</br>");
}
$db = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($db, $query )) {
mysqli_stmt_bind_param($db, $types, ...$values);
if (!mysqli_stmt_execute($db)) {
echo "Execute Error: " . mysqli_error($dbconnection);
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
//
return $db;
//
}
// main line code
$query = "SELECT * FROM Contacts WHERE First_Name = ?";
$types = "s";
$values = array("Mike");
// accept the stantement handle from the function
$db = fn_preparedStatement($query, $types, $values);
// so now you can use it
mysqli_stmt_store_result($db); //im getting the error on this line - null
Having another PHP issue that's probably something simple, but I'd really appreciate any help!
My function does a mysqli count but the $count parameter it gets bound to is not changed, even though the sql runs fine and there are no errors.
The function:
function itemsCount ($conn, $list_id) {
$count = 0;
if (!($stmt = $conn->prepare("SELECT count(uid) FROM collection.user_list_item WHERE list_id = ?"))) {
echo "Prepare failed: " . $mysqli->error;
}
if (!($stmt->bind_param('i', $list_id))) {
echo "Bind failed: " . $stmt->error;
}
if (!($stmt->execute())) {
echo "Execute failed: " . $stmt->error;
}
if (!($stmt->bind_result($count))) {
echo "Bind failed: " . $stmt->error;
}
echo $count;
$stmt->close();
return $count;
}
And the call:
public function doAdd ($conn, $list_id, $item_id) {
if ($this->itemsCount($conn, $list_id) < 20) {
...do stuff ...
}
}
Sorry the code isn't very nice, but please help point me in the right direction!
var_dump the $list_id, the param bind i, expect a integer. I expect your var to be a string which you can see with the var_dump. Either cast the string to int, or use a different param bind.
This question already has answers here:
Call to a member function bind_param() on a non-object [duplicate]
(6 answers)
Closed 6 years ago.
//function to add bm
function add_bm($new_url, $email)
{
$db = $this->dbm;
$this->new_url = $new_url;
$this->email = $email;
$sql = "select * from bookmark where email='$this->valid_user' and bm_URL='$this->new_url'";
if(!$stmt = $db->conn->query($sql))
{
echo "query failed: (" . $db->conn->errno . ") " .$db->conn->error;
}else{
//echo "can check";
//return true;
//row count
if($stmt->num_rows > 0){
echo "<b><br>Sorry ! <br> The URL had already been added . </b> ";
return false;
}else{
//return true;
// prepare and bind
$stmt = $db->conn->prepare("INSERT INTO bookmark (email, bm_URL,) VALUES (?,?)");
$stmt->bind_param("ss", $this->email, $this->new_url);
// set parameters and execute
if($stmt->execute()){
$stmt->close();
$db->conn->close();
return true;
}
}
}
}
When you do DB operations, check for errors before you proceed. Otherwise you get unexpected behaviors and puzzling errors such as this.
Your $stmt->bind_param isn't working because $stmt===false because the previous instruction errored.
if(!$stmt = $db->conn->prepare("INSERT INTO ...")){
//something went wrong. This shows the error but handle as appropriate
die($db->$conn->error);
}
//safe to continue
$stmt->bind_param(...)
This question already has answers here:
Build SELECT query with dynamic number of LIKE conditions as a mysqli prepared statement
(2 answers)
Closed 3 years ago.
I'm trying to make a function that receive a query (sql) and a parameter (array) but I receive this error:
PHP Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be
a reference, value given
My code is:
function dbRead($query, $param) {
$mysqli = new mysqli(DB::READ_HOST, DB::READ_USER, DB::READ_PASS, DB::NAME);
// Check that connection was successful.
if ($mysqli->connect_error) {
$result = "Connection error";
} else {
// Check that $conn creation succeeded
if ($conn = $mysqli->prepare($query)) {
call_user_func_array(array($conn, 'bind_param'), $param);
$conn->execute();
$result = $conn->get_result();
$result = $result->fetch_array();
$conn->close();
} else {
$result = "Prepare failed";
}
}
$mysqli->close();
return $result;
}
$test = dbRead('SELECT * FROM user WHERE id=? and email=?', array(123,'example#example.com'))
And if my function code is
function dbRead($query, $param) {
$mysqli = new mysqli(DB::READ_HOST, DB::READ_USER, DB::READ_PASS, DB::NAME);
// Check that connection was successful.
if ($mysqli->connect_error) {
$result = "Connection error";
} else {
// Check that $conn creation succeeded
if ($conn = $mysqli->prepare($query)) {
$ref = array();
foreach ($param as $key => $value) {
$ref[$key] = &$param[$key];
}
call_user_func_array(array($conn, 'bind_param'), $ref);
$conn->execute();
$result = $conn->get_result();
$result = $result->fetch_array();
$conn->close();
} else {
$result = "Prepare failed";
}
}
$mysqli->close();
return $result;
}
I receive this error
PHP Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
My PHP version is 5.4.36
I was trying to do something very similar and pieced together the solution from a few different posts on PHP References and bind_param. What's probably not immediately clear from the bind_param examples (or you forgot) is that the first argument is a string of the parameter types, one character per parameter (in your case, likely "is" for int and string), and you already got that the rest of the arguments must be references in your second function definition.
So, creating the arguments array should be something like this instead:
$ref = array("is");
foreach ($param as $value)
$ref[count($ref)] = &$value;
Though there are many ways to do it... and you should probably pass in the argument types along with the query, but MySQL seems to be relaxed when it comes to type exact types. I also prefer to pass the connection around, and support multiple result rows, e.g.:
function doRead($conn, $query, $argTypes, $args){
$success = false;
$execParams = array($argTypes);
foreach($args as $a)
$execParams[count($execParams)] = &$a;
if (!$stmt = $conn->prepare($query)){
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}else if (!call_user_func_array(array($stmt, "bind_param"), $execParams)){
echo "Param Bind failed, [" . implode(",", $args) . "]:" . $argTypes . " (" . $stmt->errno . ") " . $stmt->error;
} else if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
} else
$success = true;
$ret = array();
if($success){
$res = $stmt->get_result();
while ($row = $res->fetch_array(MYSQLI_ASSOC))
array_push($ret, $row);
}
$stmt->close();
return $ret;
}
This question already has answers here:
Call to undefined method mysqli_stmt::get_result
(10 answers)
Closed 9 years ago.
I am executing select query using mysqli ...
/** ------------ queries ---------- **/
$stmt = $mysqli->prepare("SELECT * FROM dept");
if(! $stmt)
{
echo "statement not prepared well";
}
else
{
echo $mysqli->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
// add else
else{
echo "Query is successfully executed but no result fetch";
}
if (!($res = $stmt->get_result())) {
echo "Getting result set failed: (" . $stmt->errno . ") " . $stmt->error;
}
/** ------------------------------- **/
#------result ----
var_dump($res->fetch_all());
#---------(/result)----
My problem is the execute() is working fine but cannot fetch the records ... The table has good amount of data in it ... it is showing "Query is successfully executed but no result fetch" and after it Fatal error: Call to undefined method mysqli_stmt::get_result()
What am I doing wrong .. ?
Break the following
if (!($res = $stmt->get_result())) {
to
$res = $stmt->get_result();
if( !$res ) {
Or rather to
$res = $stmt->get_result();
if( $res->num_rows == 0 ) {
The error(I didn't notice it earlier) is because
mysqli_stmt::get_result() is available only with mysqlnd.
You need to install/configure it following the guidelines here.
What am I doing wrong .. ?
You are using mysqli instead of PDO
Whole your code could be rewritten in these few lines using PDO:
$stmt = $pdo->prepare("SELECT * FROM dept");
$stmt->execute();
var_dump($stmt->fetchall());
without all these numerous if and echo.
And the difference will be even bigger when you start with prepared statements