mysqli prepare SELECT not working - php

I must be missing something really obvious or am maybe doing things in completely the wrong way, but I've been looking at this for ages and can't see what I'm doing wrong.
I'm just trying to retrieve a record from a table. It's not hard; it's just not working!
my code is
$sql = $db->prepare("SELECT * FROM user WHERE user_name=? AND user_pass=?");
$sql->bind_param('ss', $username, $password);
$result = $sql->execute();
echo "<!-- rows = $result->num_rows -->\n";
just accept that $db IS a valid connection and there are also error checking statements in the actual code. The problem is that it's not finding a row and it's not returning an error, in fact $result->num_rows isn't even zero; it's just empty.
The following code works perfectly...
$sql = "SELECT * FROM user WHERE user_name='$username' AND user_pass='$password'";
$res = $db->query($sql);
echo "<!-- rows = $res->num_rows -->\n";
So what am I doing wrong?
`

The mysqli_stmt execute method returns a boolean. To get the number of rows use $sql->num_rows instead of $res->num_rows.

There seems to be so much confusion and wrong information out there about using SELECT with prepared statements. Using documentation from us3.php.net caused me to try using a function which simply doesn't exist!
The thing I seem to be missing was a store_result statement so the logic goes more like...
$sql = $db->prepare("SELECT * FROM user WHERE user_name=? AND user_pass=?");
$sql->bind_param('ss', $username, $password);
$sql->execute();
$sql->store_result();
echo "<!-- rows = $sql->num_rows -->\n";
I hope this helps someone else who is trying to get this simplest of operations working!
I've still not worked out how (or if) I can do something like $row = $something->fetch_object() or if I'm stuck with having to use bind_result for ALL my table columns but at keast this gets me past the problem of my login page.

Related

mysqli_stmt_bind_result not returning a value

Alright so this bugs the crap out of me, and I can't seem to find anything in the PHP documentation, nor anywhere in the Google resultosphere, so maybe someone can help here.
I'm trying to make a simple request to a database to return a varchar(30).
Code:
$qryID = "select idPhotos from housesphotos where idHouse = ?";
//Prepare the query
$stmt = mysqli_prepare($link, $qryID);
$x = 106;
//Bind the login parameter to the statement
if(mysqli_stmt_bind_param($stmt, "i", $x)){
if(mysqli_stmt_execute($stmt)){
//Bind every column in the select
if(mysqli_stmt_bind_result($stmt, $photoID)){
// $photoID = mysqli_stmt_fetch($stmt);
echo $photoID;
}
}
}
if(empty($photoID)){
printf("EMPTY");
}
As you can guess the output was EMPTY. I have tried using this solution: Strange issue with mysqli_stmt_bind_result but it did not work.
To make sure that everthing was suppost to go correctly I have made the query in the mysql and it worked wonders:
select idPhotos from housesphotos where idHouse = 106
OUTPUT:
591219e92b2fe_591219e92b302
The housephotos is a varchar(30) field. I'm not sure if it's the field type that is messing with the return value. I'm not sure also if it's the connections that I made earlier on the code but I have tried unset($stmt) and other variables to solve the problem but it's not working.
Is this some kind of bug with mysqli_stmt_bind_result() or just a new person's mistake?
You're not actually fetching the results - you commented the mysqli_stmt_fetch() out. The fetch also returns a boolean, not the actual results. Uncomment that line, and remove the variable assignment to it.
$qryID = "select idPhotos from housesphotos where idHouse = ?";
//Prepare the query
$stmt = mysqli_prepare($link, $qryID);
$x = 106;
//Bind the login parameter to the statement
if(mysqli_stmt_bind_param($stmt, "i", $x)){
if(mysqli_stmt_execute($stmt)){
//Bind every column in the select
if(mysqli_stmt_bind_result($stmt, $photoID)){
mysqli_stmt_fetch($stmt); // Remove the comment and variable assignment
echo $photoID;
}
}
}
If you still don't get any results, it might be because the number of rows returned was zero (you can check that with $stmt->num_rows after executing), but since you said the query worked in phpMyAdmin, it's likely that there's some sort of error you're ignoring. To check for errors, add an else to your if conditions, and log $stmt->error inside.
http://php.net/manual/en/mysqli-stmt.fetch.php
It seems that PHP 5.4 (at least the way it's installed on Comcast servers) has a bug that causes bind-result to fail on a varchar field. Changing the field definition to "text" solves the problem.

Writing a Select Where statement in PHP and MySQL

Would someone please me with the code below, I am inexperienced in this area and my class in SQL was "A long time ago in a galaxy far, far away..." I know the connection string works because I have used it in other functions with this app. I have even used the code below for retrieving *rows from another table in another function, for the most part, except that I didn't use the WHERE clause.
First, I am able to store IP addresses in the table using a function and it is working well. Now I want to check to see if a given one exist in this table. Partial code is given below.
What seems to always return is 0 rows. I have put in test data into the table and hard-coded the $ipA, but I still get 0 rows return. Please help if possible and thanks for the effort spent.
function checkDB($ipA) {
require_once('connection.inc.php');
$resultAns = "";
//create db connection
$conn = dbConnect();
//init prepared stmt
$stmt = $conn->stmt_init();
//Set sql query for ipAddress search
//prepare the SQL query
$sql = 'SELECT * FROM ipAddress WHERE ipA = ?';
//submit the query and capture the result
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', $ipA);
$stmt = $stmt->execute();
//if qry triggers error affeted_rows value becomes -1 &
//php treats -1 as true; so test for greater than 0
$numRows = $stmt->num_rows; //not to sure about the syntax here
}
// I want to know if the query brought back something or not, I don't what
// to know exactly what, only that it found a match or did not find a match.
// echos are for testing purposes to show me where I am landing.
if ($numRows == 0) {
echo '<script type="text/javascript">window.alert("numRows = 0")</script>';
$resultAns = 0;
} elseif ($numRows == 1) {
echo '<script type="text/javascript">window.alert("numRows = 1")</script>';
$resultAns = 1;
}
return $resultAns;
}
Try storing the result after you execute
$stmt->store_result();
Use $stmt->store_result(); before you call num_rows.
While the others caught one reason that $numRows would never receive a value other than 0, the other piece of code that was flawed and caused problems was...
$stmt = $stmt->execute(); which should have been just $stmt->execute();
I must have mixed it up with other code I wrote from somewhere else.
Thanks for the answers, they did help.

How to use mysqli bind_result

im trying to use mysqli with bind_result but all i get is null values. My $stmt
number of rows is greater than 0 so i do have some data in it.
I dont realy understand what value should come into bind_result
I have read at the manual http://php.net/manual/en/mysqli-stmt.bind-result.php
And they dont explain what should i put in the bind_result.
Should i put there the column names? if yes, as strings? how do i get my wanted values?
Here is my code thanks for helping:
$sql = "SELECT * FROM comments WHERE workout_name = ? AND user = ?";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$workout_name = "rytg";
$user = "tomer";
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($comment, $commented_user);
if($stmt->num_rows > 0)
{
$response["workouts"] = array();
while ($stmt->fetch())
{
// temp user array
$workouts = array();
$workouts["comment"] = $comment;
$workouts["user"] = $commented_user;
// push single product into final response array
array_push($response["workouts"], $workouts);
}
}
Your only problem is insufficient error reporting
error_reporting(E_ALL);
ini_set('display_errors',1);
Just add these lines at the top of your code and you will be immediately informed of the exact problem with your code.
Note that on the production server you have to turn displaying errors off and logging on
I don't have a working PHP installation next to me at the moment, so I can't verify it, but I believe you might have to bind both parameters and result before you execute the query, like so:
$workout_name = "rytg";
$user = "tomer";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$stmt->bind_result($comment, $commented_user);
$stmt->execute();
I'm not too sure about store_result() either. I don't recall having to use it while retrieving the results, so you might want to try running your code without it and see what happens.

PDO mySql query not executing in for loop the second time up while calling

I have an issue, I'm looping threw a set of values and then creating a PDO mySql query with every loop, now the problem is the first query is executing and returning results, but the second upwards aren't returning results. If I manually execute the queries on the server they return results. This is weird, maybe I'm doing something wrong here. My code below
if($num_results > 0){
for($i=0;$i<$num_results;$i++){
$sql_sub = "SELECT * FROM menu_config WHERE client_id =".$client_id ." AND id =".$data[$i]['root_menu_id'];
$results_s = $pdo->query($sql_sub);
$data_s = $results_s->fetchAll(PDO::FETCH_ASSOC);
$sub_menu_title = "<strong>".$data[$i]['title']."</strong>";
if(empty($data_s[0]['title'])){
$main_menu_title = '<span style="color:#FF0000;font-weight:bold;">No Main Menu Assigned to Sub Menu</span>';
}else{
$main_menu_title = $data_s[0]['title'];
}
$men_title = $data[$i]['title']
}
}
(this may be a little more than you asked for)
You seem to be missing out on some good things that prepared statements do.
First off, you don't usually want to pass the values directly into the query. (sometime's it's necessary, but not here). By doing that, you take out all the good stuff that protects from sql injection. Instead you want to send them as parameters after you've prepared the query.
Secondly, when in a loop, you can save yourself time and resources if you're running the same query over and over by preparing the statement, and then only changing the values you send to to that prepared statement using the PDOStatement::bindParam() function.
Thirdly, fetchAll() does not take a 'fetch_style' of PDO::FETCH_ASSOC. fetch() does. But I think you can get by with the default or none using fetchAll. You'll have to check into that and see what you need. Here are the fetchAll docs
$sql_sub = "SELECT * FROM menu_config WHERE client_id = :client_id AND id = :id ";
$query = $pdo->prepare($sql_sub);
for($i=0;$i<$num_results;$i++){
$query->bindParam(':client_id', $client_id);
$query->bindParam(':id', $data[$i]['root_menu_id']);
$query->execute();
$data_s = $query->fetchAll();
$sub_menu_title = "<strong>".$data[$i]['title']."</strong>";
if(empty($data_s[0]['title'])){
$main_menu_title = '<span style="color:#FF0000;font-weight:bold;">
No Main Menu Assigned to Sub Menu</span>';
}else{
$main_menu_title = $data_s[0]['title'];
}
$men_title = $data[$i]['title'];
}

Why doesn't this prepare statement work in MYSQLI?

I created this code:
$statement = $db->prepare("SELECT * FROM phptech_contact");
$statement->execute();
$result = $statement->result_metadata();
$object = $result->fetch_object();
print_r( $object );
When I run it, it doesn't work. Can anybody tell me why it doesn't work?
I have 20 rows in this table so data should be returned.
From http://ch.php.net/manual/en/mysqli-stmt.result-metadata.php
Note: The result set returned by mysqli_stmt_result_metadata() contains only metadata. It does not contain any row results. The rows are obtained by using the statement handle with mysqli_stmt_fetch().
As long as you don't need this meta data you don't need to call this method.
$statement = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$statement->execute();
$stmt->bind_result($fld1, $fld2);
while ($stmt->fetch()) {
echo "$fld1 and $fld2<br />";
}
But I really dislike the mysqli extension. PDO is much cooler ... ;-)
$db = new PDO('...');
$stmt = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$stmt->execute();
while ($obj = $stmt->fetchObject()) {
// ...
}
or
$objs = stmt->fetchAll(PDO::FETCH_OBJ);
if you're trying to get the rows from the database, the function you need is mysqli_stmt::fetch(), not mysqli_stmt::fetch_metadata()
You're also missing a few steps. When using prepared statements, you must specify the fields you would like to return instead of using the star wildcard, and then use mysqli_stmt::bind_result() to specify which variables the database fields should be placed in.
If you're more familiar with the original MySQL extension, prepared statements have a different process to use. If your select statement has a parameter (eg., "WHERE value=?") prepared statements are definitely recommended, but for your simple query, mysqli:query() would be sufficient, and not very different from the process of mysql_query()
I believe the problem is that mysqli_stmt::result_metadata() returns a mysqli_result object without any of the actual results — it only holds metadata.
So what you want to do is use $result = $statement->bind_result(...) and then call $result->fetch() repeatedly to get the results.
One of the comments under the bind-result() article shows how to do this for a query like yours, where you don't necessarily know all of the columns being returned.

Categories