MySQLi prepared statement fails where identical regular query succeeds - php

I have a conventional query that works just fine that looks like this:
$result = $mysqli->query("SELECT value FROM activities WHERE name = 'Drywall'");
This succeeds in returning a row. However, for the purposes of diagnosing the problem I'm having with a prepared statement, I tried an identical query as a prepared statement like so:
$stmt = $mysqli->prepare("SELECT value FROM activities WHERE name = 'Drywall'");
$stmt->execute();
Despite the fact these are identical query strings, $stmt->num_rows is always 0. Why would the conventional query work, but the prepared statement not when they are the same exact query? Also, I realize including 'Drywall' in the prepared query string runs counter to the purpose of prepared statements, but I was just trying to eliminate the possibility that bind_param() was the culprit. So I was using bind_param() to fill in placeholders and that wasn't working either, despite my double-checking at runtime that the variable I was binding contained the correct value.

I think you want to use
$stmt->store_result();
before the call
$stmt->num_rows();
see last line of the descripton in the manual for $stmt->num_rows() (http://www.php.net/manual/en/mysqli-stmt.num-rows.php).

Check for proper use of the mysqli->prepare. The function depends on a parameter to be passed. It is different from passing the values ​​directly in the query but can use with another way.
Verify the manual:
http://www.php.net/manual/pt_BR/mysqli.prepare.php

Did you try something like this:
$stmt = $mysqli->prepare("SELECT value FROM activities WHERE name = 'Drywall'");
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
PS:
Prepared statements are Good. I would urge you to ALWAYS consider using them.
But in this case, a simple query would be much more efficient (would incur fewer round trips) than a prepared statement.

Related

PHP 2 Prepared Statements Error

I have 2 prepared statements in function. After I get result from first, I need one field's value from this result to be used in second statement as bind_param() function's parameter. But I was getting error, until I found out about store_result() function and used it after first statement. So can you tell or give some reference to read, why is there need to use store_result() function and why this problem arises, during using 2 prepared statements.
I don't know if I am right, but in my opinion this happens because I am not closing first statement before starting second and maybe because of both are open, some error arises.
EDIT:
I found out some information, that somehow helps me to solve this problem
Command out of sync:
This can happen, for example, if you are using mysql_use_result() and try to execute a new query before you have called mysql_free_result(). It can also happen if you try to execute two queries that return data without calling mysql_use_result() or mysql_store_result() in between.
store_result() it self for using Transfers a result set from the last query.
Example :
$stmt = $mysqli->prepare("SELECT col1,col2 FROM tabel WHERE col1= ?")
$stmt->bind_param('s', $test);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($col1,$col2);
$stmt->fetch();
You can read it in here how to use prepared-statement.
You can read this documentation how to use mysqli prepared-statement.

Getting the results of a variable length prepared statement in MySQLi

I writing an accounting website which has quite a few MySQL statements in it. To prevent SQL injection I use prepared statements for any data which is put in by the user.
In order to prevent having to write the steps of preparing and binding statements I have the following function:
function executeSql($mysqli,$query_string,$params=null,$paramtypes=null){
$nr_params=strlen($paramtypes);
$query_type = substr($query_string,0,3);
$stmt = $mysqli->prepare($query_string);
$queryParams[] = $paramtypes;
$counter=1;
if($nr_params>1){
while($counter<=$nr_params){
$queryParams[$counter]=&$params[$counter-1];
$counter++;
}
} else {
$queryParams[1]=&$params;
}
// Actual binding of the statement. Taking into account a variable numbers of '?' in the query string.
call_user_func_array(array($stmt,'bind_param'),$queryParams);
// Execution of the statement
$stmt->execute();
// Part where i'd like to have a substitute for:
$result = $stmt->get_result();
return $result;
}
In the last part I'd like to return the result because then using the result I can treat each row. The problem is that the mysqlnd driver is not installed on the production server so the function $stmt->get_result() cannot be used. I tried to bind the result into variables but then again, every query returns a different number of columns.
Anyone has an idea how to tackle this?
So in summary (in response to the comments):
How can I retrieve a results object of an executed MySQLi statement while I cannot use $stmt->get_result();
Kind regards,
EJG
PS I know the code is not flawless, e.g. if strings are used as variables to bind to the statement but that is easily fixed.
UPDATE:
I came across the function $stmt->result_metadata(); Although supposedly the function name suggests only the meta data the php documentation states that:
"If a statement passed to mysqli_prepare() is one that produces a result set, mysqli_stmt_result_metadata() returns the result object"...

Using PDO, do I really need to run two separate prepared statements to get the number of rows returned?

What is the preferred method for getting the number of rows that are returned for a SELECT state when using PDO with prepared statements?
I am currently using rowCount() but the docs say I shouldn't be using that since "most databases" don't support it (It is actually working just fine for me, so I'm tempted to keep using it. I can't find any sources that list exactly which databases do not support it, but apparently mine is fine).
Instead they recommend I use fetchColumn() but that requires writing a completely separate SQL statement that includes the COUNT(*) in my sql statement.
This is what they propose (http://php.net/manual/en/pdostatement.rowcount.php#example-1038):
//SQL TO GET ROWS TO OUTPUT
$sql = 'SELECT *
FROM properties
WHERE lister_id = :lister_id
AND lister_type = "landlord"';
$result = $dbh->prepare($sql);
$result->bindParam(':lister_id', $_SESSION['loggedin_lister_id'], PDO::PARAM_INT);
$result->execute();
//SQL TO GET NUMBER OF RETURNED ROWS
$row_num_sql = 'SELECT COUNT(*)
FROM properties
WHERE lister_id = :lister_id
AND lister_type = "landlord"';
$row_num_result = $dbh->prepare($row_num_sql);
$row_num_result->bindParam(':lister_id', $_SESSION['loggedin_lister_id'], PDO::PARAM_INT);
$row_num_result->execute();
$num_rows = $row_num_result->fetchColumn();
if($num_rows > 0) {
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'];
}
}
I find this method that requires me to write a separate and nearly identical sql statement to be redundant and a serious pain when using prepared statements. I can understand how this approach might be acceptable when using a short SQL statement with a basic query, but not in the case of a prepared statement.
1. Is there any other way I can use the fetchColumn() approach
without having to rewrite what is almost exactly the same code?
2. Where can I find an official list of which databases
rowCount() supports when using a SELECT statement? And since it is
working on the database I am currently using, can I assume it is safe
to use(assuming I am not updating my database anytime soon)?
If you don't want to use rowCount I'm think you should two query, or you can use fetchAll and count(fetchAll) for rowCount
the second way, Use SELECT *,COUNT(*) ...

Prepared MySQLi statements

I've always used PDO statements, but for some reason I can't persuade the server guy to install PDO for php, but I do have MySQLi, I have no clue what I'm doing wrong, I do not get a connection error and I do not get a query error no matter how I try to output one. Here's what I'm doing.
include 'MySQLiConnect.php';
if($stmt = $mysqli->prepare("SELECT * FROM zipCodeTable WHERE zip_code = ?")){
$stmt->bind_param("s", '07110');
$stmt->execute();
$stmt->bind_result($resultsArray);
$stmt->fetch();
foreach($resultsArray as $columnData){
$matchingZipcode = $columnData['zip_code'];
$matchingTimezone = $columnData['time_zone'];
}
$stmt->close();
}
echo $matchingZipcode.', '.$matchingTimezone;
This is basically just to confirm a users zipcode, never used MySQLi prepared statements before, I tryed to do it straight from the manual, not sure what I'm doing wrong. Thank you for taking the time to read this.
You're trying to "bind" a literal string. You can't do this. You must bind a variable.
Change
$stmt->bind_param("s", '07110');
To
$string = '07110';
$stmt->bind_param("s", $string);
Also, when you bind a result you must provide a variable for each field returned.
For example:
$stmt->bind_result($zipCode, $timeZone);
This is slightly problematic when using SELECT *. You might be interested in checking out this comment for how you might want to go about it: http://www.php.net/manual/en/mysqli-stmt.bind-result.php#85470

mysqli prepared statement with fetch_assoc

my goal here is to be able to get a variable (with php) and use it in a prepared statement (with mysqli), and then fetch_assoc. For some reason this code will not work (no errors). I've rtm and I haven't found anything combining fetch_assoc with prepared statements, so I'm not sure if it's even possible. Any help to get this working is appreciated, here's my code currently.
$where = $_GET['section'];
$mysqli = mysqli_connect("localhost", "root", "","test");
if($stmt = mysqli_prepare($mysqli,"SELECT title, img, active, price FROM ? ORDER by ID limit 5 ")){
mysqli_stmt_bind_param($stmt, 's', $where);
mysqli_stmt_execute($mysqli);
mysqli_stmt_fetch($mysqli);
while($row = mysqli_fetch_assoc($stmt)){
if($row['active']=="yes"){
echo 'the rest of my stuff goes here';
From the PHP website page for mysqli->prepare (with emphasis added to the most relevant part):
Note:
The markers are legal only in certain places in SQL statements. For
example, they are allowed in the VALUES() list of an INSERT statement
(to specify column values for a row), or in a comparison with a column
in a WHERE clause to specify a comparison value.
However, they are not allowed for identifiers (such as table or column
names), in the select list that names the columns to be returned by a
SELECT statement), or to specify both operands of a binary operator
such as the = equal sign. The latter restriction is necessary because
it would be impossible to determine the parameter type. In general,
parameters are legal only in Data Manipulation Language (DML)
statements, and not in Data Definition Language (DDL) statements.
Assuming you can get past that problem, your use of mysqli is a little confused. You correctly bind your parameters and execute, but you've mixed up two different ways of getting at your results. Either
Use mysqli_stmt_get_result to fetch the result set and then use mysqli_fetch_assoc on that, or
Bind your results with mysqli_stmt_bind_result, and then use mysqli_stmt_fetch to fetch the next set of results into your bound variables. (Usually you'd iterate over the results using something like while(mysqli_stmt_fetch($stmt)){ //do stuff here }
Another way style, we can write it below:
$mysqli=new mysqli("host","user","pass","db");
$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', $variable);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()){
....
}

Categories