PHP and MYSQLi - Bind parameters using loop and store in array? - php

Below is my code for the function I am using to retrieve multiple data from my table, but I would like to use bind_result($array[0],...,..) to be generated automatically depending on number of fields i am selecting in the query.
for example..
$query=select a,b,c,d,e from table;//selecting 5 fields
......
$stmt->execute();$stmt->bind_result($retrieve[0],$retrieve[1],$retrieve[2],$retrieve[3],$retrieve[4]);
(the bind_result for 5 values should be automatically generated)
Help will be appreciated ...Thanks
$query="SELECT comment, userid,UNIX_TIMESTAMP(dtime)
FROM comment_updates
WHERE updateid=46546
ORDER BY dtime DESC
LIMIT 10 ";
if($stmt = $this->conn->prepare($query)) {
$stmt->execute();
$stmt->bind_result($comments[0],$comments[1],$comments[2]);
$i=0;
while($stmt->fetch()){
$i++;
$name='t'.$i;
$$name = array($comments[0],$comments[1],$comments[2]);
}
return array($i,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10);
$stmt->close();
}

This should get you started:
http://php.net/manual/en/mysqli-stmt.result-metadata.php
This will get you the number of fields in your resultset via mysqli_num_fields().
This should be the size of your $retrieve array.
As bind_result doesn't take an array as an argument, you'll need to use call_user_func_array to achieve this:
call_user_func_array(array($stmt, 'bind_result'), $retrieve_references);
$retrieve_references should be an array of references to the elements in $retrieve. Using $retrieve itself in call_user_func_array will trigger an error.

Related

Using Positional Placeholders with WHERE IN Returns Only One Result

I'm trying to incorporate a WHERE IN statement into an already-working query using PDO. I've gone through and dynamically created positional placeholders using the count of an indexed array, and looped through said array to bind each value. However when this is all said and done I'm only getting one result, specifically a result matching the last value I dynamically bound.
To add to this, if I simply implode $arrayToCheck with a comma as a delimiter in place of $placeholderSpots, I get the full 24 results I'm expecting.
$arrayToCheck = json_decode($listFromDatabase); //This is a Python List converted to a string using Python's json.dumps, which was then passed into a database table.
$timePeriod = 0;
$rowLimit = 2500;
$placeholderSpots = implode(", ", array_fill(0, count($arrayToCheck), "?"));
$toPull = $GLOBALS['MainDatabase']->prepare("SELECT * FROM datatable WHERE timecolumn >= ? AND idcolumn IN ($placeholderSpots) ORDER BY timecolumn DESC LIMIT ?");
$toPull->bindParam(1, $timePeriod, PDO::PARAM_INT);
$tempCounter = 2;
foreach ($arrayToCheck as $eachID) {
$toPull->bindParam($tempCounter, $eachID, PDO::PARAM_INT);
$tempCounter++;
}
$toPull->bindParam($tempCounter, $rowLimit, PDO::PARAM_INT);
if ($toPull->execute()) {
while ($pulledData = $toPull->fetch(PDO::FETCH_ASSOC)) {
//Data Is Processed Here
}
}
You need to replace bindParam() with bindValue().
foreach ($arrayToCheck as $eachID) {
$toPull->bindValue($tempCounter++, $eachID, PDO::PARAM_INT);
}
The bindParam() method bind by reference to the variable. You assign a new value each time to the same variable when looping over the array, so the variable doesn't change, only the value does. The end result is that you have bound the same variable multiple times that holds the last value from the array.

Can't call PHP function multiple times

I am trying to fix my previous problem with an extra query.
However, when I am trying to make multiple calls to my PHP function it just shows the first one and not both.
Code:
<?php function test($colour)
{
$pdo = new PDO("pgsql:host=localhost;dbname=testdb","teun",""); // or use a global one
//$pdo = $GLOBALS['pdo'];
$sth = $pdo->prepare("SELECT * FROM threads WHERE cat_id = :cat_id AND thread_date=(
SELECT max(thread_date) FROM threads
)");
$sth->bindParam(':cat_id', $colour, PDO::PARAM_STR, 12);
$sth->execute();
$result = $sth->fetch();
echo $result ["thread_name"];
}
?>
(yes, I know this is unsafe but I want to achieve my thing first before I work on the safe part).
I call it using test ($row['extra_cat_id'])
Thanks!
fetch() only fetches 1 row, see PDOStatement::fetch.
Either iterate using fetch() to fetch 1 by 1, or use the fetchAll() method to fetch all results, see PDOStatement::fetchAll

Using a prepared statement in php & mysqli

I am using prepared statements for the first time. And i cannot get the select to work.
For some reason, it returns all the records but i cannot get them into variables. I know it returns all the records because if i add echo '1'; to the loop it echo's 1 for each record.
Any assistance would be great. The code is below:
function builditems($quote_id){
if ($stmt = $this->link->prepare("SELECT * FROM `0_quotes_items` WHERE `quote_id` = ?")) {
// Bind a variable to the parameter as a string.
$stmt->bind_param("i", $quote_id);
// Execute the statement.
$stmt->execute();
while ($row = $stmt->fetch()) {
echo $row['id'];
}
// Close the prepared statement.
$stmt->close();
}
}
UPDATE:
in the error log, i see the following error after adding the while ($row = $stmt->fetch_assoc()) { like suggested:
PHP Fatal error: Call to undefined method mysqli_stmt::fetch_assoc()
I found a link that the same issue was had, but i do not understand how to implement the fix.
Any assistance would be great, with regards to a example.
How to remove the fatal error when fetching an assoc array
The PHP MySQLi fetch method does not access query data using brackets notation: $row['id'].
So I see two options to remedy: first find this line:
while ($row = $stmt->fetch()) {
...and modify it to, either, first add the bind_result method, and then access the data a bit differently:
$stmt->bind_result($id, $other, $whatnot); // assuming 3 columns retrieved in the query
while ($row = $stmt->fetch()) {
echo "$id $other $whatnot<br>";
}
...or, first access the result object's fetch_assoc method and use fetch_assoc instead of fetch:
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
Now you can use table column names as keys to access query data in your loop: $row['id'].
PHP MySQLi method fetch requires you to use bind_result. Doing this allows you to call your data by the variable names you've bound it to.
To use the field name as the result array index, such as: $row['id'], you need to use the PHP MySQLi fetch_assoc method. And to use fetch_assoc you need to first get the result object in order to access the fetch_assoc method.

Retrieving PHP Prepared Statement field data

I am using the Mysqli extension and a PHP Prepared Statement SELECT; I don't know how many fields I have in the SELECT until I after I do the
$stmt->execute();
$fieldcnt = $stmt->field_count;
Because this, I am having problems doing a
$stmt->bind_result(list of parms);
Namely, since I don't know how many fields have been returned, I don't know how to contruct the "list of parms."
So, I need some advice on how I access the fields returned;
Don't use bind_result, and use fetch_assoc().
This will return an associated array for each row:
while ($row = $stmt->fech_assoc()) {
print_r($row);
}
You can leverage call_user_func_array() to accomplish this task -- if you absolutely must use bind_result().
// create an array the size of the number of parameters
$params = array_fill(0, $fieldcnt, null);
// call bind_result, resulting in every column of the result to be
// bound to a value in $params
call_user_func_array(array($stmt, 'bind_result'), $params);
// take a look at all the params
print_r($params);

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