Turning mysql query into prepared statement - php

I'm trying to turn the below query into a prepared statement, but I'm having no luck so far. I've attached one of my attempts. The idea is I'm using this to check how many rows are returned using mysqli_num_rows afterward.
$sql2=mysqli_query($bd, "SELECT address FROM member WHERE address='".$address."'");
This is my attempt at creating a prepared statement.
$ustmt = $bd->prepare("SELECT username FROM member WHERE username = ?");
$ustmt->bind_param("s", $username);
$sql2 = $ustmt->execute();
Is this correct? And if so, how do I then check the number of rows returned into $sql2 ?

Yes, your preparation and execution is correct.
The execute call returns a boolean value, which will be true if successful else false (if false, the $stmt->error property will be set with error message).
This is worth checking before continuing, cause if its false, there will be no result.
Same with the preparation, if the $mysqli->prepare(...) call returns false, the $mysqli->error will be set with the error message.
After execution, you can fetch the number of affected rows by either the $num_rows property, in case its a SELECT statement, or the $affected_rows property in other cases.
echo $stmt->num_rows;
Or, you can fetch the mysqli_result object from the statement with the get_result() method.
The mysqli_result object contains the public field $num_rows, so you can check row count by:
$res = $stmt->get_result();
echo $res->num_rows;
For other methods in the mysqli_result object, i recommend checking the docs.

Related

mysqli_stmt_get_result and mysqli_fetch_all incompatible?

I'm trying to bind parameters (for security) and then get the result into an array, so I created code like the following. The problem is that it doesn't work: $arr is null. (BTW I know the query in getList works.)
if ($stmt = mysqli_prepare($con, "call getList(?)")) {
mysqli_stmt_bind_param($stmt, 's', $userInputSearch);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$arr = mysqli_fetch_all($result, MYSQLI_ASSOC);
$jsonArr = json_encode($arr);
echo $jsonArr;
Note that I've got mysqli_fetch_all to work when using mysqli_query().
On mysqli_fetch_all reference, I found this comment:
Also, mysqli_fetch_all works only for buffered result sets, which are
the default for mysqli_query. MYSQLI_USE_RESULT will be supported in
5.3.4+ However, it makes little sense to use it this way, materialising unbuffered sets. In this case choose STORE_RESULT, and
fetch_all won't copy the data, but reference it, as it is stored
already in mysqlnd.
I discovered that prepared statements return unbuffered results, so I tried using $result = mysqli_stmt_store_result($stmt) instead of $result = mysqli_stmt_get_result($stmt); However that didn't help.
That leaves me not completely at a loss — I understand that I could loop to load the data one row at a time, but I really don't want to have to loop in PHP just to do something as simple as get an array from a prepared statement. Is there a way to acquire and deal with the result set as one object?
I've just reread documentation...
I have no possibility to test mysql right now.
But just a guess:
mysqli_fetch_all ( mysqli_result $result ...
Parameters result Procedural style only: A result set identifier
returned by mysqli_query(), mysqli_store_result() or
mysqli_use_result().
I want to highlight that all functions mysqli_query(), mysqli_store_result() mysqli_use_result() belongs to mysqli class, not to stmt and they return type mysqli_result
but you are trying to use mysqli_stmt_get_result($stmt);
mysqli_result mysqli_stmt_get_result ( mysqli_stmt $stmt )
...
Return Values
Returns a resultset or FALSE on failure.
So this function return type resultset not mysqli_result.
So you have to change your code to use no mysqli_stmt
so change :
if ($stmt = mysqli_prepare($con, "call getList(?)")) {
mysqli_stmt_bind_param($stmt, 's', $userInputSearch);
mysqli_stmt_execute($stmt);
to
$result = mysqli_query ( $con , "call getList(".mysqli_real_escape_string($userInputSearch).")" );
, or
just change your line:
$arr = mysqli_fetch_all($result, MYSQLI_ASSOC);
to
$arr = array()
while ($row = $result->fetch_array())
{
arr[] = $row ;
}
Sorry if any error, have no possibility to trace and debug right now, hope it is helpful.

mySQL returns result even though the database is empty

This SQL query return result and then session save empty variable like $_SESSION["fbid"] = $user->fbid; and array would be Array ( [fbid] => ).
$result = $mysqli->query("SELECT * FROM `users` WHERE `fbid` = '$fbid'") or die(mysqli_error());
if ($result) {
$user = $result->fetch_object();
...
The main question is, why is it passing through if ($result) when there isn't any records in the database?
You are saying if($result)
This states that your if will always be true.
You need to say if($result == 1) for example.
You need to have $result equal, or not equal.
That is how an if statement works. However, you are saying "if query" which wont work anyways, you need to say something like,
if(mysqli_num_rows($result) > 0){
$user = $result->fetch_object();
}
mysqli->query returns either true, or false or mysqli_result object.
Both true and mysqli_result object will pass if($result), and false returned in case of error. Getting empty result is not an error.
If you need to check if your query returns empty result, use $num_rows property, for example.
Your test if ($result) will only fail if mysqli_query() fails, perhaps with a syntax error.
If you have a valid query your test will pass. This is true even if your valid query returns an empty set (Finding nothing is a valid result).
You need to check the result of the query to ensure your query actually succeeded, but this is different from checking whether it returned anything.
Try
$result = $mysqli->query("select...");
if ($result->num_rows) {
// do stuff
}
mysqli::query returns FALSE if a query fails. In this case, it did not fail - it was successfully executed, and returned zero rows.
If you want to check for an empty result set, check the return value of fetch_object:
$user = $result->fetch_object();
if ($user) {
# do stuff...

MySQLI Prepared Statement: num_rows & fetch_assoc

Below is some poorly written and heavily misunderstood PHP code with no error checking. To be honest, I'm struggling a little getting my head around the maze of PHP->MySQLi functions! Could someone please provide an example of how one would use prepared statements to collect results in an associative array whilst also getting a row count from $stmt? The code below is what I'm playing around with. I think the bit that's throwing me off is using $stmt values after store_result and then trying to collect an assoc array, and I'm not too sure why...
$mysqli = mysqli_connect($config['host'], $config['user'], $config['pass'], $config['db']);
$stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
$stmt->bind_param('i', $core['id']);
$result = $stmt->execute();
$stmt->store_result();
if ($stmt->num_rows >= "1") {
while($data = $result->fetch_assoc()){
//Loop through results here $data[]
}
}else{
echo "0 records found";
}
I feel a little cheeky just asking for code, but its a working demonstration of my circumstances that I feel I need to finally understand what's actually going on. Thanks a million!
I searched for a long time but never found documentation needed to respond correctly, but I did my research.
$stmt->get_result() replace $stmt->store_result() for this purpose.
So, If we see
$stmt_result = $stmt->get_result();
var_dump($stmt_result);
we get
object(mysqli_result)[3]
public 'current_field' => int 0
public 'field_count' => int 10
public 'lengths' => null
public 'num_rows' => int 8 #That we need!
public 'type' => int 0
Therefore I propose the following generic solution. (I include the bug report I use)
#Prepare stmt or reports errors
($stmt = $mysqli->prepare($query)) or trigger_error($mysqli->error, E_USER_ERROR);
#Execute stmt or reports errors
$stmt->execute() or trigger_error($stmt->error, E_USER_ERROR);
#Save data or reports errors
($stmt_result = $stmt->get_result()) or trigger_error($stmt->error, E_USER_ERROR);
#Check if are rows in query
if ($stmt_result->num_rows>0) {
# Save in $row_data[] all columns of query
while($row_data = $stmt_result->fetch_assoc()) {
# Action to do
echo $row_data['my_db_column_name_or_ALIAS'];
}
} else {
# No data actions
echo 'No data here :(';
}
$stmt->close();
$result = $stmt->execute(); /* function returns a bool value */
reference : http://php.net/manual/en/mysqli-stmt.execute.php
so its just sufficient to write $stmt->execute(); for the query execution.
The basic idea is to follow the following sequence :
1. make a connection. (now while using sqli or PDO method you make connection and connect with database in a single step)
2. prepare the query template
3. bind the the parameters with the variable
4. (set the values for the variable if not set or if you wish to change the values) and then Execute your query.
5. Now fetch your data and do your work.
6. Close the connection.
/*STEP 1*/
$mysqli = mysqli_connect($servername,$usrname,$pswd,$dbname);
/*STEP 2*/
$stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
/*Prepares the SQL query, and returns a statement handle to be used for further operations on the statement.*/
//mysqli_prepare() returns a statement object(of class mysqli_stmt) or FALSE if an error occurred.
/* STEP 3*/
$stmt->bind_param('i', $core['id']);//Binds variables to a prepared statement as parameters
/* STEP 4*/
$result = $stmt->execute();//Executes a prepared Query
/* IF you wish to count the no. of rows only then you will require the following 2 lines */
$stmt->store_result();//Transfers a result set from a prepared statement
$count=$stmt->num_rows;
/*STEP 5*/
//The best way is to bind result, its easy and sleek
while($data = $stmt->fetch()) //use fetch() fetch_assoc() is not a member of mysqli_stmt class
{ //DO what you wish
//$data is an array, one can access the contents like $data['attributeName']
}
One must call mysqli_stmt_store_result() for (SELECT, SHOW, DESCRIBE, EXPLAIN), if one wants to buffer the complete result set by the client, so that the subsequent mysqli_stmt_fetch() call returns buffered data.
It is unnecessary to call mysqli_stmt_store_result() for other queries, but if you do, it will not harm or cause any notable performance in all cases.
--reference: php.net/manual/en/mysqli-stmt.store-result.php
and http://www.w3schools.com/php/php_mysql_prepared_statements.asp
One must look up the above reference who are facing issue regarding this,
My answer may not be perfect, people are welcome to improve my answer...
If you would like to collect mysqli results into an associative array in PHP you can use fetch_all() method. Of course before you try to fetch the rows, you need to get the result with get_result(). execute() does not return any useful values.
For example:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($config['host'], $config['user'], $config['pass'], $config['db']);
$mysqli->set_charset('utf8mb4'); // Don't forget to set the charset!
$stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
$stmt->bind_param('i', $core['id']);
$stmt->execute(); // This doesn't return any useful value
$result = $stmt->get_result();
$data = $result->fetch_all(MYSQLI_ASSOC);
if ($data) {
foreach ($data as $row) {
//Loop through results here
}
} else {
echo "0 records found";
}
I am not sure why would you need num_rows, you can always use the array itself to check if there are any rows. An empty array is false-ish in PHP.
Your problem here is that to do a fetch->assoc(), you need to get first a result set from a prepared statement using:
http://php.net/manual/en/mysqli-stmt.get-result.php
And guess what: this function only works if you are using MySQL native driver, or "mysqlnd". If you are not using it, you'll get the "Fatal error" message.
You can try this using the mysqli_stmt function get_result() which you can use to fetch an associated array. Note get_result returns an object of type mysqli_result.
$stmt->execute();
$result = $stmt->get_result(); //$result is of type mysqli_result
$num_rows = $result->num_rows; //count number of rows in the result
// the '=' in the if statement is intentional, it will return true on success or false if it fails.
if ($result_array = $result->fetch_assoc(MYSQLI_ASSOC)) {
//loop through the result_array fetching rows.
// $ rows is an array populated with all the rows with an associative array with column names as the key
for($j=0;$j<$num_rows;$j++)
$rows[$j]=$result->fetch_row();
var_dump($rows);
}
else{
echo 'Failed to retrieve rows';
}

mysqli_query - return values

I am using the PHP function mysqli_query to run a SELECT query.
What does mysqli_query return if the query runs successfully, but the query finds no matches?
Per the manual:
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object. For other successful queries mysqli_query() will return TRUE.
A query that runs but returns no results is still considered a "successful query", since the query did run in the database and an empty result set is a legitimate response. This means the query will still return a mysqli_result object, and if you check its row count (either via $result->num_rows in the object-oriented style or mysqli_num_rows($result) in the procedural style) it will return 0.
A Mysqli_query object, than you can use mysqli_num_rows to count the number of rows returned. So:
if(mysqli_num_rows($query) > 0 ){
// Do something
}
if ($result = $mysqli->query("SELECT * FROM data"))
{
$count = $result->num_rows;
printf("Result set has %d rows.\n", $count);
$result->close();
}
From reference:
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or
EXPLAIN queries mysqli_query() will return a mysqli_result object. For
other successful queries mysqli_query() will return TRUE.

MySQLi num_rows returns 0

Here's my code
$stmt = $conn->mysqli->stmt_init();
$stmt = $conn->mysqli->prepare('SELECT Username, EmailVerified, Blocked FROM user WHERE Email = ? AND SLANumber = ? AND Password = ?');
$stmt->bind_param('ssb', $_POST['EmailID'], $_POST['SLANumber'], $_POST['Password']);
$stmt->execute();
$stmt->store_result();
$result = $stmt->get_result();
if($result->num_rows == 0){
echo 'No rows found';
}
else{
// Continue processing here
.....
}
The code always echoes No rows found. A day or two before, it was working fine.
As expected, running the query directly gives the desired result.
What's wrong with the code?
Don't use store_result and get_result together in the same statement.
Use store_result method with "num_rows", "bind_result" and "fetch".
For get_result method, use "affected_rows" and "fetch_array". You can still use the "num_rows" property in the income get_result method as shown below.
$stmt->execute();
// $stmt->store_result();
$result = $stmt->get_result();
if(result->num_rows == 0){
...
}
OR
$stmt->execute();
// $stmt->store_result();
$result = $stmt->get_result();
if($stmt->affected_rows == 0){
...
}
To fix your problem remove this line:
$stmt->store_result();
The problem is that you used two methods which are in conflict with each other.
$stmt->store_result();
$result = $stmt->get_result();
Both of these methods fetch the results. store_result() fetches the results internally and stores them in the statement object. I would advise to avoid this method whenever possible. It is difficult to use. get_result() fetches the results and saves them in a separate object. Once the results are fetched from MySQL, they cannot be fetched again. Use only one of these methods at a time.
In your case you first stored the results in mysqli_stmt and then fetched an empty result set into $result. $result will contain 0 rows, because all of the records have already been stored in the statement. To get the number of rows stored there use $stmt->num_rows.
Both mysqli_stmt and mysqli_result classes have the num_rows property. The key is to use the appropriate one.
num_rows is a property of mysqli_stmt, not of a result resource. So you should be doing:
$result = $stmt->get_result();
// Also check strict comparison against int 0,
// to avoid incorrect equality with boolean FALSE
if($stmt->num_rows === 0){
echo 'No rows found';
}

Categories