Getting multiple rows with prepared statement [duplicate] - php

This question already has answers here:
Call to undefined method mysqli_stmt::get_result
(10 answers)
Closed 11 months ago.
I'm quite new to prepared statements and am not sure I am doing this right.
Here is what I try:
$currgame = 310791;
$sql = "SELECT fk_player_id, player_tiles, player_draws, player_turn, player_passes, swapped FROM ".$prefix."_gameplayer WHERE fk_game_id = ?";
$stmt = $mysqli->stmt_init();
$data = array();
if($stmt->prepare($sql)){
$stmt->bind_param('i', $currgame);
$stmt->execute();
$fk_player_id = null; $player_tiles = null; $player_draws = null; $player_turn = null; $player_passes = null; $swapped = null;
$stmt->bind_result($fk_player_id, $player_tiles, $player_draws, $player_turn, $player_passes, $swapped);
$res = $stmt->get_result();
while ($row = $res->fetch_assoc()){
$data[] = $row;
}
$stmt->close();
}
// to display own games
foreach ($data as $row) {
if ($row['fk_player_id'] == $playerid) {
$udraws = $row['player_draws']+1;
$upass = $row['player_passes'];
$uswaps = $row['swapped'];
echo 'uDraws: '.$udraws.'<br>';
echo 'uPass: '.$upass.'<br>';
echo 'uSwaps: '.$uswaps.'<br><br>';
}
}
// to display other games
foreach ($data as $row) {
if ($row['fk_player_id'] != $playerid) {
$opponent = $row['fk_player_id'];
$oppTiles = $row['player_tiles'];
$odraws = $row['player_draws']+1;
$opass = $row['player_passes'];
$oswaps = $row['swapped'];
echo 'oID: '.$opponent.'<br>';
echo 'oTiles: '.$oppTiles.'<br>';
echo 'oDraws: '.$odraws.'<br>';
echo 'oPass: '.$opass.'<br>';
echo 'oSwaps: '.$oswaps.'<br><br>';
}
}
I get an "ServerError" when trying to run this: It is the $res = $stmt->get_result(); that makes the error, but not sure why.
PHP Fatal error: Call to undefined method mysqli_stmt::get_result() in /home/mypage/public_html/TEST/preparedstatement.php on line 61

Depending on your PHP/MySQL setup you may not be able to use get_result().
The way to get around this is to bind the results.
For example:
$stmt->execute();
$fk_player_id = null; $player_tiles = null; $player_draws = null; $player_turn = null; $player_passes = null; $swapped = null;
$stmt->bind_result($fk_player_id, $player_tiles, $player_draws, $player_turn, $player_passes, $swapped);
while ($stmt->fetch()) { // For each row
/* You can then use the variables declared above, which will have the
new values from the query every time $stmt->execute() is ran.*/
}
For more information click here

Since I don't see it in your code, make sure you're instantiating the mysqli object before trying to query on it:
$mysqli = new mysqli("127.0.0.1", "user", "password", "mydb");
if($mysqli->connect_error){
die("$mysqli->connect_errno: $mysqli->connect_error");
}
Also, a ServerError would certainly show up in your logs and point you in the right direction.

while (mysqli_stmt_fetch($stmt)) {
printf ("%s (%s)\n", $name, $code);
}
This might help you:
http://php.net/manual/en/mysqli-stmt.fetch.php

Related

returning multiple rows from mysql in php

I'm trying to write a PHP-script that will fetch multiple rows from MySQL and return them as a JSONObject, the code works if I try to only fetch 1 row but if I try to get more than one at a time the return string is empty.
$i = mysql_query("select * from database where id = '$v1'", $con);
$temp = 2;
while($row = mysql_fetch_assoc($i)) {
$r[$temp] = $row;
//$temp = $temp +1;
}
If I write the code like this it returns what I expect it to, but if I remove the // from the second row in the while loop it will return nothing. Can anyone explain why this is and what I should do to solve it?
You are using an obsolete mysql_* library.
You are SQL injection prone.
Your code is silly and makes no sense.
If you really wan to stick to it, why simply not do:
while($row = mysql_fetch_assoc($i)) {
$r[] = $row;
}
echo json_encode($r);
And finally, an example using PDO:
$database = 'your_database';
$user = 'your_db_user';
$pass = 'your_db_pass';
$pdo = new \PDO('mysql:host=localhost;dbname='. $database, $user, $pass);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
try
{
$stmt = $pdo->prepare("SELECT * FROM your_table WHERE id = :id");
$stmt->bindValue(':id', $id);
$stmt->execute();
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
catch(\PDOException $e)
{
$results = ['error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine());
}
echo json_encode($results);
You don't need the $temp variable. You can add an element to an array with:
$r[] = $row;

Run a call from a function PHP

i'm building an website using php and html, im used to receiving data from a database, aka Dynamic Website, i've build an CMS for my own use.
Im trying to "simplify" the receiving process using php and functions.
My Functions.php looks like this:
function get_db($row){
$dsn = "mysql:host=".$GLOBALS["db_host"].";dbname=".$GLOBALS["db_name"];
$dsn = $GLOBALS["dsn"];
try {
$pdo = new PDO($dsn, $GLOBALS["db_user"], $GLOBALS["db_pasw"]);
$stmt = $pdo->prepare("SELECT * FROM lp_sessions");
$stmt->execute();
$row = $stmt->fetchAll();
foreach ($row as $row) {
echo $row['session_id'] . ", ";
}
}
catch(PDOException $e) {
die("Could not connect to the database\n");
}
}
Where i will get the rows content like this: $row['row'];
I'm trying to call it like this:
the snippet below is from the index.php
echo get_db($row['session_id']); // Line 22
just to show whats in all the rows.
When i run that code snippet i get the error:
Notice: Undefined variable: row in C:\wamp\www\Wordpress ish\index.php
on line 22
I'm also using PDO just so you would know :)
Any help is much appreciated!
Regards
Stian
EDIT: Updated functions.php
function get_db(){
$dsn = "mysql:host=".$GLOBALS["db_host"].";dbname=".$GLOBALS["db_name"];
$dsn = $GLOBALS["dsn"];
try {
$pdo = new PDO($dsn, $GLOBALS["db_user"], $GLOBALS["db_pasw"]);
$stmt = $pdo->prepare("SELECT * FROM lp_sessions");
$stmt->execute();
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
echo $row['session_id'] . ", ";
}
}
catch(PDOException $e) {
die("Could not connect to the database\n");
}
}
Instead of echoing the values from the DB, the function should return them as a string.
function get_db(){
$dsn = "mysql:host=".$GLOBALS["db_host"].";dbname=".$GLOBALS["db_name"];
$dsn = $GLOBALS["dsn"];
$result = '';
try {
$pdo = new PDO($dsn, $GLOBALS["db_user"], $GLOBALS["db_pasw"]);
$stmt = $pdo->prepare("SELECT * FROM lp_sessions");
$stmt->execute();
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
$result .= $row['session_id'] . ", ";
}
}
catch(PDOException $e) {
die("Could not connect to the database\n");
}
return $result;
}
Then call it as:
echo get_db();
Another option would be for the function to return the session IDs as an array:
function get_db(){
$dsn = "mysql:host=".$GLOBALS["db_host"].";dbname=".$GLOBALS["db_name"];
$dsn = $GLOBALS["dsn"];
$result = array();
try {
$pdo = new PDO($dsn, $GLOBALS["db_user"], $GLOBALS["db_pasw"]);
$stmt = $pdo->prepare("SELECT * FROM lp_sessions");
$stmt->execute();
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
$result[] = $row['session_id'];
}
}
catch(PDOException $e) {
die("Could not connect to the database\n");
}
return $result;
}
Then you would use it as:
$sessions = get_db(); // $sessions is an array
and the caller can then make use of the values in the array, perhaps using them as the key in some other calls instead of just printing them.
As antoox said, but a complete changeset; change row to rows in two places:
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
echo $row['session_id'] . ", ";
}
Putting this at the start of the script after <?php line will output interesting warnings:
error_reporting(E_ALL|E_NOTICE);
To output only one row, suppose the database table has a field named id and you want to fetch row with id=1234:
$stmt = $pdo->prepare("SELECT * FROM lp_sessions WHERE id=?");
$stmt->bindValue(1, "1234", PDO::PARAM_STR);
I chose PDO::PARAM_STR because it will work with both strings and integers.

How To Return mysqli_fetch_assoc in While Loop As Variable in PHP Function?

I have this PHP function :
function userParent($Username)
{
global $con;
$Result = mysqli_query($con, "SELECT Username FROM Family WHERE Parent = '$Username' LIMIT 10");
$row = mysqli_fetch_assoc($Result);
return $row;
}
that function should give me 10 rows in array, but why I just have a value in array? I tried to test that codes outside function bracket and try to add WHILE loop like this :
while ($row = mysqli_fetch_assoc($Result)){
print_r($row);
}
and it works. I got my 10 rows in array format. but it prints the result to the screen. how to make it as variable so it can be returned in function?
thanks.
UPDATE : according to Phil's answer, now here's my complete code :
<?php
function userParent(mysqli $con, $username) {
$stmt = $con->prepare('SELECT Username FROM Family WHERE Parent = ? LIMIT 10');
$stmt->bind_param('s', $username);
$stmt->execute();
$res = $stmt->get_result();
return $res->fetch_all(MYSQLI_ASSOC);
}
$DbServer = 'localhost';
$DbUser = 'username';
$DbPassword = 'password';
$DbName = 'dbname';
$mysqli = new mysqli($DbServer, $DbUser, $DbPassword, $DbName);
$arrayParent = userParent($mysqli, 'root');
print_r($arrayParent);
?>
but I got this error message :
Fatal error: Call to undefined method mysqli_stmt::get_result() in /home/myhome/public_html/test.php on line 6
Use return:
function userParent(mysqli &$dbms, $username){
// You need to "escape" strings, which you would use in direct queries.
// OR BETTER: use mysqli prepared statements with parameter binding.
$username = mysqli_real_escape_string($dbms, $username);
$result = mysqli_query($dbms, "SELECT Username FROM Family WHERE Parent = '$username' LIMIT 10");
// Create temporary array for resultset:
$buffer = array();
// Fetch data to temporary buffer:
while ($row = mysqli_fetch_assoc($result)){
$buffer[] = $row;
}
// Free result set:
$result->free();
// Return buffer to global scope:
return $buffer;
}
$users = userParent($con, 'John');
var_dump($users);
Try mysqli_result::fetch_all instead
function userParent(mysqli $con, $username) {
$stmt = $con->prepare('SELECT Username FROM Family WHERE Parent = ? LIMIT 10');
if ($stmt === false) {
throw new Exception($con->error, $con->errno);
}
$stmt->bind_param('s', $username);
$stmt->execute();
$res = $stmt->get_result();
return $res->fetch_all(MYSQLI_ASSOC);
}
Then call it like this
$parents = userParent($mysqli, 'some username');
Read these in case you're not aware of prepared statements and parameter binding
http://www.php.net/manual/en/mysqli.prepare.php
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
Update
Apparently (undocumented), the mysqli_stmt::get_result() method is only available when using the mysqlnd driver. If you cannot use this driver, try this alternative
function userParent(mysqli $con, $username) {
$stmt = $con->prepare('SELECT Username FROM Family WHERE Parent = ? LIMIT 10');
if ($stmt === false) {
throw new Exception($con->error, $con->errno);
}
$stmt->bind_param('s', $username);
$stmt->execute();
$parent = null;
$parents = array();
$stmt->bind_result($parent);
while($stmt->fetch()) {
$parents[] = $parent;
}
return $parents;
}

$stmt-num_rows ( Return 0 ) [duplicate]

This question already has an answer here:
$stmt->num_rows returning 0 even after calling store_result
(1 answer)
Closed 9 years ago.
i am just trying to learn prepared statement and i am following the PHP manual to guide me through, i have checked the answers regarding this problem on stackoverflow but, i can't find any solutions, the $stmt->num_rows always ( Return 0 )
there is a post on stackoverflow discussed the problem and they advised to use
$stmt->store_result() just before the $stmt-num_rows, but the $stmt->num_rows return 0
some one please can tell me what i am doing wrong here.... i am just sick of the procedural style coding and i want to enhance my skills with prepared statement
here is the function down below
function get_all()
{
// ** Initializing the Connection
$mysqli = Connect();
$sql = ( ' SELECT * FROM `users` ' );
$stmt = $mysqli->prepare($sql);
$stmt->execute();
$res = $stmt->get_result();
echo $num_count = $stmt->num_rows();
$user = array();
for ($counter = 0; $row = $res->fetch_assoc(); $counter++)
{
$user[$counter] = $row;
}
return $user;
}
// This is the second update
function get_all()
{
// ** Initializing the Connection
$mysqli = Connect();
$sql = ( ' SELECT * FROM `users` ' );
$stmt = $mysqli->prepare($sql);
$stmt->execute();
$res = $stmt->get_result();
echo $num_count = $stmt->num_rows;
$user = array();
while($row = $res->fetch_assoc())
{
$user[] = $row;
}
return $user;
}
// third update
function get_alll()
{
// ** Initializing the Connection
$mysqli = Connect();
// no need to use * character,
// need to write query this way
$sql = ( ' SELECT `id`,`fname`,`lname`,`uname`,`email` FROM `users` ' );
$stmt = $mysqli->prepare($sql);
// here need to use bind param
$stmt->bind_result( $id, $fname, $lname, $uname, $email);
$stmt->execute();
// it's important to store the result
// before using num rows
$res = $stmt->store_result();
echo $num_count = $stmt->num_rows;
//
while($stmt->fetch())
{
echo $fname;
}
}
num_rows is a property, not a method, try with $stmt->num_rows without brackets

Return an array from mysqli stmt query

I'm trying to convert a site to use prepared mysql statements, however I'm having some trouble replacing my use of fetch_array().
The comments on php.net offer a solution which I would have thought should work but for some reason I'm getting strange undefined constant errors when calling a function via call_user_func_array() can someone suggest a better way of doing it?
Here's the function I'm using at the moment. I've dumbed it down a bit for posting on here (it's part of a larger class which extends mysqli and handles error catching etc) so sorry if I've made any mistakes copy and pasting it.
public static function stmt_bind_assoc(&$stmt, &$out) {
$data = mysqli_stmt_result_metadata($stmt);
$fields = array();
$out = array();
$fields[0] = $stmt;
$count = 1;
while($field = mysqli_fetch_field($data)) {
$fields[$count] = &$out[$field->name];
$count++;
}
call_user_func_array(mysqli_stmt_bind_result, $fields);
}
public function fetch_array($rawQuery) {
$stmt = $this->prepare($rawQuery);
$row = array();
self::stmt_bind_assoc($stmt, $row);
$result = $stmt->fetch();
$stmt->free();
return $result;
}
The errors I get are:
Notice: Use of undefined constant mysqli_stmt_bind_result - assumed 'mysqli_stmt_bind_result'
Fatal error: Call to undefined method mysqli_stmt::free()
The first error comes from your call_user_func_array statement: you need quotes around the mysqli_stmt_bind_result, otherwise PHP assumes it's a constant.
And there's no free() function in mysqli_stmt, use $stmt->free_result() instead.
$servername = "localhost"; $username = "root"; $password = ""; $dbnam = "test";
// Create connection $conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection if (mysqli_connect_errno()) {
die("Connection failed: %s\n" . mysqli_connect_errno()); }
$stmt = mysqli_prepare($conn, "SELECT * FROM myguests") or
die(mysqli_error($conn)); mysqli_stmt_execute($stmt);
$data = mysqli_stmt_result_metadata($stmt);
$fields = array();
$out = array();
$fields[0] = &$stmt;
$count = 1;
while($field = mysqli_fetch_field($data)) {
$fields[$count] = &$out[$field->name];
$count++;
}
call_user_func_array("mysqli_stmt_bind_result", $fields);
while(mysqli_stmt_fetch($stmt)) print_r($out);
$stmt->close(); $conn->close();
Works great on me, hope it helps

Categories