Mysql search by multiple fields - php

I am creating search option using php .I want to do search when user give multiple fields according to given fields i need fetch records from the database.to get clear idea about what i need to do below is the interface of the search option
when user click go in form submit i need to get user given filds and fetch record according to given search crieteria
so i have looked many options and i found below as efficient
$query = 'SELECT *
FROM user
WHERE 1 = 1 ';
if(!empty($serviceNumber) )
{
$query .= ' and serviceNumber = ? ';
$params[] = $serviceNumber;
}
if(!empty($name))
{
$query .= ' and userName = ? ';
$params[] = $name;
}
if(!empty($status))
{
$query .= ' and status = ? ';
$params[] =$status;
}
if(!empty($params))
{
$sth->execute($params);
$dbh->prepare($query);
$result= mysqli_query($dbcon,$sth);
if(!$result )
{
die('Could not get data: ' . mysqli_error());
}
}
else
{
echo 'Missing Values';
}
but i got $sth as undefined variable so is there efficient way or can i correct this error.if any one can help appreciated.

This code would work (even if you reverse the wrong order prepare an execute called in) only with PDO.
For mysqli you have to always bind your values explicitly, which is a distinct pain in the back. Luckily, since PHP version 5.6 there is an argument unpacking operator that helps:
$stmt = $db->prepare($query);
$types = str_repeat('s', count($params));
$statement->bind_param($types, ...$params);
$statement->execute();
$res = $statement->get_result();
$data = $res->fetch_all();
however, if your PHP version doesn't meet this requirement or get_result() function is not supported, I would strongly suggest to forget about mysqli and turn to PDO. Which will make your code a lot simpler and - which is way more important - would work with any PHP version regardless:
$sth = $dbh->prepare($query);
$sth->execute($params);
$data = $sth->fetchAll();

Related

Register/Login mysqli_stmt_get_result() Error help me [duplicate]

Here's my code:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();
I get the error on last line as: Call to undefined method mysqli_stmt::get_result()
Here is the code for conn.php:
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
/**
* #var Resource
*/
var $mysqli = null;
function __construct(){
try{
if(!$this->mysqli){
$this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
if(!$this->mysqli)
throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
}
}
catch(Exception $ex){
echo "ERROR: ".$e->getMessage();
}
}
}
If I write this line:
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
It prints 'Statement NOT prepared'. If I run the query directly in the IDE replacing ? marks with values, it works fine. Please note that $conn object works fine in other queries in the project.
Any help please.......
Please read the user notes for this method:
http://php.net/manual/en/mysqli-stmt.get-result.php
It requires the mysqlnd driver... If it isn't installed on your webspace you will have to work with bind_result() & fetch()!
With PHP version 7.2 I just used nd_mysqli instead of mysqli and it worked as expected.
Steps to enable it into godaddy hosting server-
Login to cpanel.
Click on "Select PHP version".
As provided the snapshot of the latest configurations uncheck "mysqli" and enable "nd_mysqli".
So if the MySQL Native Driver (mysqlnd) driver is not available, and therefore using bind_result and fetch instead of get_result, the code becomes:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
/* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
Your system is missing the mysqlnd driver!
If you are able to install new packages on your (Debian/Ubuntu-based) server, install the driver:
sudo apt-get install php5-mysqlnd
and then restart your web server:
sudo /etc/init.d/apache2 restart
for those searching for an alternative to $result = $stmt->get_result() I've made this function which allows you to mimic the $result->fetch_assoc() but using directly the stmt object:
function fetchAssocStatement($stmt)
{
if($stmt->num_rows>0)
{
$result = array();
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$result[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params);
if($stmt->fetch())
return $result;
}
return null;
}
as you can see it creates an array and fetches it with the row data, since it uses $stmt->fetch() internally, you can call it just as you would call mysqli_result::fetch_assoc (just be sure that the $stmt object is open and result is stored):
//mysqliConnection is your mysqli connection object
$stmt = $mysqli_connection->prepare($query);
$stmt->execute();
$stmt->store_result();
while($assoc_array = fetchAssocStatement($stmt))
{
//do your magic
}
I know this was already answered as to what the actual problem is, however I want to offer a simple workaround.
I wanted to use the get_results() method however I didn't have the driver, and I'm not somewhere I can get that added. So, before I called
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
I created an empty array, and then just bound the results as keys in that array:
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
so that those results could easily be passed into methods or cast to an object for further use.
Hope this helps anyone who's looking to do something similar.
I was getting this same error on my server - PHP 7.0 with the mysqlnd extension already enabled.
Solution was for me (thanks to this page) was to deselect the mysqli extension and select nd_mysqli instead.
NB - You may be able to access the extensions selector in your cPanel. (I access mine via the Select PHP Version option.)
Here is my alternative. It is object-oriented and is more like mysql/mysqli things.
class MMySqliStmt{
private $stmt;
private $row;
public function __construct($stmt){
$this->stmt = $stmt;
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$this->row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
}
public function fetch_array(){
if($this->stmt->fetch()){
$result = array();
foreach($this->row as $k => $v){
$result[$k] = $v;
}
return $result;
}else{
return false;
}
}
public function free(){
$this->stmt->close();
}
}
Usage:
$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
array_push($arr, $row);
//for example, use $row['id']
}
$result->free();
//for example, use the $arr
I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result() is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result() offers - without using get_result().
get_result() is/was often combined with fetch_array() to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
However, if get_result() is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result(). Or, how to migrate legacy code that uses get_result() to run without it (e.g. using bind_result() instead) - while impacting the rest of the code as little as possible.
It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result(). bind_result() expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.
Of course, the code could easily be modified as follows:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result(), which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results(). If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the select clause, the migration will be very labor intensive and prone to error if we use a solution like the one above.
Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result() function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the select clause of the query.
Searching on the internet, I found a number of solutions that use bind_param() with call_user_func_array()
(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Of course, the for() loop can be collapsed into one line to make it more compact.
I hope this helps anyone who is looking for a solution using bind_result() to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result(). Comments welcome.
I have written two simple functions that give the same functionality as $stmt->get_result();, but they don't require the mysqlnd driver.
You simply replace
$result = $stmt->get_result(); with $fields = bindAll($stmt);
and
$row= $stmt->get_result(); with $row = fetchRowAssoc($stmt, $fields);.
(To get the numbers of returned rows you can use $stmt->num_rows.)
You just have to place these two functions I have written somewhere in your PHP Script. (for example right at the bottom)
function bindAll($stmt) {
$meta = $stmt->result_metadata();
$fields = array();
$fieldRefs = array();
while ($field = $meta->fetch_field())
{
$fields[$field->name] = "";
$fieldRefs[] = &$fields[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
$stmt->store_result();
//var_dump($fields);
return $fields;
}
function fetchRowAssoc($stmt, &$fields) {
if ($stmt->fetch()) {
return $fields;
}
return false;
}
How it works:
My code uses the $stmt->result_metadata(); function to figure out how many and which fields are returned and then automatically binds the fetched results to pre-created references. Works like a charm!

Php Mysql prepared Statements not working since uploading to produktion [duplicate]

Here's my code:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();
I get the error on last line as: Call to undefined method mysqli_stmt::get_result()
Here is the code for conn.php:
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
/**
* #var Resource
*/
var $mysqli = null;
function __construct(){
try{
if(!$this->mysqli){
$this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
if(!$this->mysqli)
throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
}
}
catch(Exception $ex){
echo "ERROR: ".$e->getMessage();
}
}
}
If I write this line:
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
It prints 'Statement NOT prepared'. If I run the query directly in the IDE replacing ? marks with values, it works fine. Please note that $conn object works fine in other queries in the project.
Any help please.......
Please read the user notes for this method:
http://php.net/manual/en/mysqli-stmt.get-result.php
It requires the mysqlnd driver... If it isn't installed on your webspace you will have to work with bind_result() & fetch()!
With PHP version 7.2 I just used nd_mysqli instead of mysqli and it worked as expected.
Steps to enable it into godaddy hosting server-
Login to cpanel.
Click on "Select PHP version".
As provided the snapshot of the latest configurations uncheck "mysqli" and enable "nd_mysqli".
So if the MySQL Native Driver (mysqlnd) driver is not available, and therefore using bind_result and fetch instead of get_result, the code becomes:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
/* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
Your system is missing the mysqlnd driver!
If you are able to install new packages on your (Debian/Ubuntu-based) server, install the driver:
sudo apt-get install php5-mysqlnd
and then restart your web server:
sudo /etc/init.d/apache2 restart
for those searching for an alternative to $result = $stmt->get_result() I've made this function which allows you to mimic the $result->fetch_assoc() but using directly the stmt object:
function fetchAssocStatement($stmt)
{
if($stmt->num_rows>0)
{
$result = array();
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$result[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params);
if($stmt->fetch())
return $result;
}
return null;
}
as you can see it creates an array and fetches it with the row data, since it uses $stmt->fetch() internally, you can call it just as you would call mysqli_result::fetch_assoc (just be sure that the $stmt object is open and result is stored):
//mysqliConnection is your mysqli connection object
$stmt = $mysqli_connection->prepare($query);
$stmt->execute();
$stmt->store_result();
while($assoc_array = fetchAssocStatement($stmt))
{
//do your magic
}
I know this was already answered as to what the actual problem is, however I want to offer a simple workaround.
I wanted to use the get_results() method however I didn't have the driver, and I'm not somewhere I can get that added. So, before I called
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
I created an empty array, and then just bound the results as keys in that array:
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
so that those results could easily be passed into methods or cast to an object for further use.
Hope this helps anyone who's looking to do something similar.
I was getting this same error on my server - PHP 7.0 with the mysqlnd extension already enabled.
Solution was for me (thanks to this page) was to deselect the mysqli extension and select nd_mysqli instead.
NB - You may be able to access the extensions selector in your cPanel. (I access mine via the Select PHP Version option.)
Here is my alternative. It is object-oriented and is more like mysql/mysqli things.
class MMySqliStmt{
private $stmt;
private $row;
public function __construct($stmt){
$this->stmt = $stmt;
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$this->row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
}
public function fetch_array(){
if($this->stmt->fetch()){
$result = array();
foreach($this->row as $k => $v){
$result[$k] = $v;
}
return $result;
}else{
return false;
}
}
public function free(){
$this->stmt->close();
}
}
Usage:
$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
array_push($arr, $row);
//for example, use $row['id']
}
$result->free();
//for example, use the $arr
I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result() is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result() offers - without using get_result().
get_result() is/was often combined with fetch_array() to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
However, if get_result() is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result(). Or, how to migrate legacy code that uses get_result() to run without it (e.g. using bind_result() instead) - while impacting the rest of the code as little as possible.
It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result(). bind_result() expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.
Of course, the code could easily be modified as follows:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result(), which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results(). If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the select clause, the migration will be very labor intensive and prone to error if we use a solution like the one above.
Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result() function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the select clause of the query.
Searching on the internet, I found a number of solutions that use bind_param() with call_user_func_array()
(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Of course, the for() loop can be collapsed into one line to make it more compact.
I hope this helps anyone who is looking for a solution using bind_result() to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result(). Comments welcome.
I have written two simple functions that give the same functionality as $stmt->get_result();, but they don't require the mysqlnd driver.
You simply replace
$result = $stmt->get_result(); with $fields = bindAll($stmt);
and
$row= $stmt->get_result(); with $row = fetchRowAssoc($stmt, $fields);.
(To get the numbers of returned rows you can use $stmt->num_rows.)
You just have to place these two functions I have written somewhere in your PHP Script. (for example right at the bottom)
function bindAll($stmt) {
$meta = $stmt->result_metadata();
$fields = array();
$fieldRefs = array();
while ($field = $meta->fetch_field())
{
$fields[$field->name] = "";
$fieldRefs[] = &$fields[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
$stmt->store_result();
//var_dump($fields);
return $fields;
}
function fetchRowAssoc($stmt, &$fields) {
if ($stmt->fetch()) {
return $fields;
}
return false;
}
How it works:
My code uses the $stmt->result_metadata(); function to figure out how many and which fields are returned and then automatically binds the fetched results to pre-created references. Works like a charm!

Can anybody help me adequate this code (PHP, mysqli_stmt::get_result / mysqli_stmt::bind_result and mysqli_stmt::fetch [duplicate]

Here's my code:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();
I get the error on last line as: Call to undefined method mysqli_stmt::get_result()
Here is the code for conn.php:
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
/**
* #var Resource
*/
var $mysqli = null;
function __construct(){
try{
if(!$this->mysqli){
$this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
if(!$this->mysqli)
throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
}
}
catch(Exception $ex){
echo "ERROR: ".$e->getMessage();
}
}
}
If I write this line:
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
It prints 'Statement NOT prepared'. If I run the query directly in the IDE replacing ? marks with values, it works fine. Please note that $conn object works fine in other queries in the project.
Any help please.......
Please read the user notes for this method:
http://php.net/manual/en/mysqli-stmt.get-result.php
It requires the mysqlnd driver... If it isn't installed on your webspace you will have to work with bind_result() & fetch()!
With PHP version 7.2 I just used nd_mysqli instead of mysqli and it worked as expected.
Steps to enable it into godaddy hosting server-
Login to cpanel.
Click on "Select PHP version".
As provided the snapshot of the latest configurations uncheck "mysqli" and enable "nd_mysqli".
So if the MySQL Native Driver (mysqlnd) driver is not available, and therefore using bind_result and fetch instead of get_result, the code becomes:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
/* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
Your system is missing the mysqlnd driver!
If you are able to install new packages on your (Debian/Ubuntu-based) server, install the driver:
sudo apt-get install php5-mysqlnd
and then restart your web server:
sudo /etc/init.d/apache2 restart
for those searching for an alternative to $result = $stmt->get_result() I've made this function which allows you to mimic the $result->fetch_assoc() but using directly the stmt object:
function fetchAssocStatement($stmt)
{
if($stmt->num_rows>0)
{
$result = array();
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$result[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params);
if($stmt->fetch())
return $result;
}
return null;
}
as you can see it creates an array and fetches it with the row data, since it uses $stmt->fetch() internally, you can call it just as you would call mysqli_result::fetch_assoc (just be sure that the $stmt object is open and result is stored):
//mysqliConnection is your mysqli connection object
$stmt = $mysqli_connection->prepare($query);
$stmt->execute();
$stmt->store_result();
while($assoc_array = fetchAssocStatement($stmt))
{
//do your magic
}
I know this was already answered as to what the actual problem is, however I want to offer a simple workaround.
I wanted to use the get_results() method however I didn't have the driver, and I'm not somewhere I can get that added. So, before I called
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
I created an empty array, and then just bound the results as keys in that array:
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
so that those results could easily be passed into methods or cast to an object for further use.
Hope this helps anyone who's looking to do something similar.
I was getting this same error on my server - PHP 7.0 with the mysqlnd extension already enabled.
Solution was for me (thanks to this page) was to deselect the mysqli extension and select nd_mysqli instead.
NB - You may be able to access the extensions selector in your cPanel. (I access mine via the Select PHP Version option.)
Here is my alternative. It is object-oriented and is more like mysql/mysqli things.
class MMySqliStmt{
private $stmt;
private $row;
public function __construct($stmt){
$this->stmt = $stmt;
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$this->row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
}
public function fetch_array(){
if($this->stmt->fetch()){
$result = array();
foreach($this->row as $k => $v){
$result[$k] = $v;
}
return $result;
}else{
return false;
}
}
public function free(){
$this->stmt->close();
}
}
Usage:
$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
array_push($arr, $row);
//for example, use $row['id']
}
$result->free();
//for example, use the $arr
I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result() is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result() offers - without using get_result().
get_result() is/was often combined with fetch_array() to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
However, if get_result() is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result(). Or, how to migrate legacy code that uses get_result() to run without it (e.g. using bind_result() instead) - while impacting the rest of the code as little as possible.
It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result(). bind_result() expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.
Of course, the code could easily be modified as follows:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result(), which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results(). If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the select clause, the migration will be very labor intensive and prone to error if we use a solution like the one above.
Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result() function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the select clause of the query.
Searching on the internet, I found a number of solutions that use bind_param() with call_user_func_array()
(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Of course, the for() loop can be collapsed into one line to make it more compact.
I hope this helps anyone who is looking for a solution using bind_result() to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result(). Comments welcome.
I have written two simple functions that give the same functionality as $stmt->get_result();, but they don't require the mysqlnd driver.
You simply replace
$result = $stmt->get_result(); with $fields = bindAll($stmt);
and
$row= $stmt->get_result(); with $row = fetchRowAssoc($stmt, $fields);.
(To get the numbers of returned rows you can use $stmt->num_rows.)
You just have to place these two functions I have written somewhere in your PHP Script. (for example right at the bottom)
function bindAll($stmt) {
$meta = $stmt->result_metadata();
$fields = array();
$fieldRefs = array();
while ($field = $meta->fetch_field())
{
$fields[$field->name] = "";
$fieldRefs[] = &$fields[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
$stmt->store_result();
//var_dump($fields);
return $fields;
}
function fetchRowAssoc($stmt, &$fields) {
if ($stmt->fetch()) {
return $fields;
}
return false;
}
How it works:
My code uses the $stmt->result_metadata(); function to figure out how many and which fields are returned and then automatically binds the fetched results to pre-created references. Works like a charm!

Implementing extensible search query in Mysqli

I am trying to migrate to Mysqli and I got my Mysql code to search for parameters like this:
$querySt = "SELECT userID FROM myTable";
if (isset($_POST["UserID"])) {
if (ctype_digit($_POST["UserID"])) {
addWhereIfNoHave();
$in_userID = mysql_real_escape_string($_POST["UserID"]);
$querySt .= " UserID = '$in_userID'";
}
}
if (isset($_POST["name"])) {
addWhereIfNoHave();
$in_name = mysql_real_escape_string($_POST["name"]);
$querySt .= " imgName LIKE LOWER('%$in_name%')";
}
if (isset($_POST["ScoreLessThan"])) {
if (ctype_digit($_POST["ScoreLessThan"])) {
addWhereIfNoHave();
$in_ScoreLessThan = mysql_real_escape_string($_POST["ScoreLessThan"]);
$querySt .= " Score < '$in_ScoreLessThan'";
}
}
...
...
there are other if statements here looking for other post data, and
they keep on adding parameters into mysql query string just like above.
...
...
//this function is called in those if statements above. It either adds "WHERE" or "AND".
function addWhereIfNoHave(){
global $querySt;
if (strpos($querySt, 'WHERE') !== false){
$querySt .= " OR";
return true;
}else{
$querySt .= " WHERE";
return false;
}
}
This function works ok looking for all the parameters input from PHP post. However, I am migrating this to Mysqli, and I have a bit of trouble converting this code to Mysqli version. For example,
$stmt = $conn->prepare("SELECT userID FROM myTable WHERE UserID = ? AND name= ?");
$stmt->bind_param('ss', $userid, $name);
Suppose, I wanna search the table using 2 variables, I bind 2 variables like above, but in the case of my Mysql above, I keep on extending additional parameters into the string before executing the mysql query.
But for Mysqli, how can we do this? Is it possible to bind additional parameters and extending the string for prepare statement like Mysql code above? How should this problem be approach for Mysqli?
My current problem is mainly with the bind_param. I could concatenate the search query further and add all the '?' into the prepare statement, but with different variable types and number variables needed to be specified in bind_param, this is where I am stuck.

Value <br of type java.lang.String cannot be converted to JSONObject// php error [duplicate]

Here's my code:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();
I get the error on last line as: Call to undefined method mysqli_stmt::get_result()
Here is the code for conn.php:
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
/**
* #var Resource
*/
var $mysqli = null;
function __construct(){
try{
if(!$this->mysqli){
$this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
if(!$this->mysqli)
throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
}
}
catch(Exception $ex){
echo "ERROR: ".$e->getMessage();
}
}
}
If I write this line:
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
It prints 'Statement NOT prepared'. If I run the query directly in the IDE replacing ? marks with values, it works fine. Please note that $conn object works fine in other queries in the project.
Any help please.......
Please read the user notes for this method:
http://php.net/manual/en/mysqli-stmt.get-result.php
It requires the mysqlnd driver... If it isn't installed on your webspace you will have to work with bind_result() & fetch()!
With PHP version 7.2 I just used nd_mysqli instead of mysqli and it worked as expected.
Steps to enable it into godaddy hosting server-
Login to cpanel.
Click on "Select PHP version".
As provided the snapshot of the latest configurations uncheck "mysqli" and enable "nd_mysqli".
So if the MySQL Native Driver (mysqlnd) driver is not available, and therefore using bind_result and fetch instead of get_result, the code becomes:
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
/* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
Your system is missing the mysqlnd driver!
If you are able to install new packages on your (Debian/Ubuntu-based) server, install the driver:
sudo apt-get install php5-mysqlnd
and then restart your web server:
sudo /etc/init.d/apache2 restart
for those searching for an alternative to $result = $stmt->get_result() I've made this function which allows you to mimic the $result->fetch_assoc() but using directly the stmt object:
function fetchAssocStatement($stmt)
{
if($stmt->num_rows>0)
{
$result = array();
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$result[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params);
if($stmt->fetch())
return $result;
}
return null;
}
as you can see it creates an array and fetches it with the row data, since it uses $stmt->fetch() internally, you can call it just as you would call mysqli_result::fetch_assoc (just be sure that the $stmt object is open and result is stored):
//mysqliConnection is your mysqli connection object
$stmt = $mysqli_connection->prepare($query);
$stmt->execute();
$stmt->store_result();
while($assoc_array = fetchAssocStatement($stmt))
{
//do your magic
}
I know this was already answered as to what the actual problem is, however I want to offer a simple workaround.
I wanted to use the get_results() method however I didn't have the driver, and I'm not somewhere I can get that added. So, before I called
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
I created an empty array, and then just bound the results as keys in that array:
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
so that those results could easily be passed into methods or cast to an object for further use.
Hope this helps anyone who's looking to do something similar.
I was getting this same error on my server - PHP 7.0 with the mysqlnd extension already enabled.
Solution was for me (thanks to this page) was to deselect the mysqli extension and select nd_mysqli instead.
NB - You may be able to access the extensions selector in your cPanel. (I access mine via the Select PHP Version option.)
Here is my alternative. It is object-oriented and is more like mysql/mysqli things.
class MMySqliStmt{
private $stmt;
private $row;
public function __construct($stmt){
$this->stmt = $stmt;
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$this->row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
}
public function fetch_array(){
if($this->stmt->fetch()){
$result = array();
foreach($this->row as $k => $v){
$result[$k] = $v;
}
return $result;
}else{
return false;
}
}
public function free(){
$this->stmt->close();
}
}
Usage:
$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
array_push($arr, $row);
//for example, use $row['id']
}
$result->free();
//for example, use the $arr
I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result() is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result() offers - without using get_result().
get_result() is/was often combined with fetch_array() to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
However, if get_result() is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result(). Or, how to migrate legacy code that uses get_result() to run without it (e.g. using bind_result() instead) - while impacting the rest of the code as little as possible.
It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result(). bind_result() expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.
Of course, the code could easily be modified as follows:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result(), which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results(). If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the select clause, the migration will be very labor intensive and prone to error if we use a solution like the one above.
Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result() function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the select clause of the query.
Searching on the internet, I found a number of solutions that use bind_param() with call_user_func_array()
(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Of course, the for() loop can be collapsed into one line to make it more compact.
I hope this helps anyone who is looking for a solution using bind_result() to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result(). Comments welcome.
I have written two simple functions that give the same functionality as $stmt->get_result();, but they don't require the mysqlnd driver.
You simply replace
$result = $stmt->get_result(); with $fields = bindAll($stmt);
and
$row= $stmt->get_result(); with $row = fetchRowAssoc($stmt, $fields);.
(To get the numbers of returned rows you can use $stmt->num_rows.)
You just have to place these two functions I have written somewhere in your PHP Script. (for example right at the bottom)
function bindAll($stmt) {
$meta = $stmt->result_metadata();
$fields = array();
$fieldRefs = array();
while ($field = $meta->fetch_field())
{
$fields[$field->name] = "";
$fieldRefs[] = &$fields[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
$stmt->store_result();
//var_dump($fields);
return $fields;
}
function fetchRowAssoc($stmt, &$fields) {
if ($stmt->fetch()) {
return $fields;
}
return false;
}
How it works:
My code uses the $stmt->result_metadata(); function to figure out how many and which fields are returned and then automatically binds the fetched results to pre-created references. Works like a charm!

Categories