PhP $stmt->fetch() while loop keeps replacing existing data - php

Running $stmt->fetch() in a while() loop replaces all previously collected data in an object with the last record, even if you push it to an array in the loop.
I have a simple database called dbemployee
I've written a small script to get all the employees above a specific age.
Heres my code:
<?php
$conn = mysqli_connect("localhost", "root", "", "test");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$output = new stdClass();
$employee = new stdClass();
// $ageCheck = $_POST['ageCheck'];
$ageCheck = 18;
$sql = "SELECT ID, vemail, vname, vage FROM dbemployee WHERE vage > ?";
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param("s",$ageCheck);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($ID, $vemail, $vname, $vage);
if ($stmt->num_rows > 0) {
while ($stmt->fetch()) {
$employee->ID = $ID;
$employee->vemail = $vemail;
$employee->vname = $vname;
$employee->vage = $vage;
$output->data[] = $employee;
}
} else {
$output->data = "";
}
$output->response = "SUCCESS";
}
header('Content-Type: application/json');
print_r($output);
?>
Surprisingly all I'm getting is 5 entries of the last result as if the last result is replacing previous results.

You need to create an instance inside the loop, otherwise it will point to the same memory address:
while ($stmt->fetch()) {
$employee = new stdClass;
$employee->ID = $ID;
...
You can check this in the docs (https://www.php.net/manual/en/language.oop5.basic.php):
When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by cloning it.

Related

Flattening a SQL query result for PHP array

I have a SQL table (modules) with two columns (id, name). Now I can retrieve the rows from this through a PHP script but what I want is to use the value of id as the key, and the value of name as the value, in a multidimensional array. Then I want to be able to encode those into a JSON, retaining the relationship between key/value. I've muddled something together but it returns null.
the relevant code from index.php
$mod1 = $core["module1"];
$mod2 = $core["module2"];
$modules = $db->getModulesById($mod1, $mod2); //module names & ids
$response["module"]["mod1"] = $modules[$mod1];
$response["module"]["mod2"] = $modules[$mod2];
$response["module"]["mod1name"] = $modules[$mod1]["name"];
$response["module"]["mod2name"] = $modules[$mod2]["name"];
echo json_encode($response);
The function from DB_Functions.php
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD);
// Check connection
if (!$con)
{
die("Connection error: " . mysqli_connect_error());
}
// selecting database
mysqli_select_db($con, DB_DATABASE) or die(mysqli_connect_error());
$query = "SELECT * FROM modules WHERE id= '$mod1' OR id='$mod2'";
$result = mysqli_query($con, $query);
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
// process each row
//each element of $arr now holds an id and name
$arr[] = $row;
}
// return user details
return mysqli_fetch_array($arr);
close();
}
I've looked around but I'm just not 'getting' how the query return is then broken down into key/value for a new array. If someone could ELI5 I'd appreciate it. I'm just concerned with this aspect, it's a personal project so I'm not focusing on security issues as yet, thanks.
You are pretty well there
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
// Check connection
if (!$con) {
die("Connection error: " . mysqli_connect_error());
}
$query = "SELECT * FROM modules WHERE id= '$mod1' OR id='$mod2'";
$result = mysqli_query($con, $query);
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
$arr[] = $row;
}
// here is wrong
//return mysqli_fetch_array($arr);
// instead return the array youy created
return $arr;
}
And call it and then just json_encode the returned array
$mod1 = $core["module1"];
$mod2 = $core["module2"];
$modules = $db->getModulesById($mod1, $mod2); //module names & ids
$response['modules'] = $modules;
echo json_encode($response);
You should really be using prepared and paramterised queries to avoid SQL Injection like this
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
// Check connection
if (!$con) {
die("Connection error: " . mysqli_connect_error());
}
$sql = "SELECT * FROM modules WHERE id= ? OR id=?";
$stmt = $con->prepare($sql);
$stmt->bind_param('ii', $mod1, $mod2);
$stmt->execute();
$result = $stmt->get_result();
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
$arr[] = $row;
}
// here is wrong
//return mysqli_fetch_array($arr);
// instead return the array youy created
return $arr;
}
mysqli_fetch_array requires the result of a mysqli_query result. Passing the constructed array to mysqli_fetch_array() is not going to work.
If you want to have a specific value from a row to use as its key, you can't resolve this with any mysqli_* function. You could however construct it yourself:
while($row = mysqli_fetch_assoc($result)) {
// process each row
//each element of $arr now holds an id and name
$arr[$row['id']] = $row;
}
mysqli_close($con);
return $arr;
You should close the connection before returning the result, code positioned after a return will not be executed.

PhP MySQL get ceratin items from database and echo them

I need some help and I can't figure it out,i tried searching the internet but I found nothing
So I'm using this code from w3schools
<?php
$servername = "localhost"; //Obviously this are set to my parameters
$username = "username"; //Obviously this are set to my parameters
$password = "password"; //Obviously this are set to my parameters
$dbname = "myDB"; //Obviously this are set to my parameters
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM People";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
//Some code goes here
}
} else {
echo "0 results";
}
$conn->close();
?>
How can I modify this code to echo certain items only?
EXAMPLE
I have 10 items in talbe People (Table people contains id,age,name,gender)
I want to echo out 3 out of 10 People by using their ID which are 1 trough 10
I know i can use this AND id IN(1, 5, 9)"; This just echoes them out 1 after another
Is there a way to echo out id 1 goes here , id 5 goes here and than id 9 goes there like in 3 different places with 3 different codes or something? is this even possible?
You could use:
class people
{
public function people()
{
$sql = $this->conn->prepare("SELECT * FROM `people`");
$sql->execute();
$result = $sql->fetch(PDO::FETCH_OBJ);
return $result;
}
}
then when you want certain information you could simply use in say index.php:
$fetch = new people();
$info = $fetch->people();
you can then run simple echo's such as $info->name or $info->id etc etc..
Depending on how you're searching for the user you could just add
WHERE `userid` = :id
$sql->bindParam(':id', $userid);
and add $userid into the people($userid)
But this will vary depending on how you're pulling out specific users.
use this code
<?php
//using PDO
try
{
$conn = new PDO('mysql:dbhost=myhost;dbname=mydbname;', 'user','pass');
}
catch (PDOException $e)
{
echo $e->getMessage();
}
$getId = $conn->query("
SELECT * FROM users
WHERE id = 1
AND id = 5
AND id = 9
");
while ($ids = $getId->fetch(PDO::FETCH_OBJ)
{
echo $getId->id . '<br>';
}

setting php boolean to FALSE not working

I have no records in a table called assessment
I have a function:
function check_assessment_record($p_id, $a_id, $c){
$dataexistsqry="SELECT * FROM assessments WHERE (pupil_id=$p_id && assessblock_id=$a_id)" ;
$resultt = $c->query($dataexistsqry);
if ($resultt->num_rows > 0) {
echo '<p>set $de = true</p>';
$de=TRUE;
}else{
echo '<p>set $de = false</p>';
$de=FALSE;
}
return $de;
$dataexists->close();
}; //end function
I call the function thus:
$thereisdata = check_assessment_record($pupil_id, $assessblock_id, $conn);
However my function is printing out nothing when I was expecting FALSE. It prints out true when there's a record.
When I get the result in $thereisdata I want to check for if its TRUE or FALSE but its not working.
I looked at the php manual boolean page but it didn't help
It seems that you are passing the database connection as an object using the variable $c in your function parameter. This tells me that you would greatly benefit by creating a class and using private properties/variables. Also, there are many errors in your code that shows me what you are trying to achieve, some errors are the way you are closing your db connection using the wrong variable, or how you place the close connection method after the return, that will never be reached.
Anyway, I would create a database class where you can then call on specific functions such as the check_assessment_record() as you wish.
Here's how I would redo your code:
<?php
class Database {
private $conn;
function __construct() {
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "test";
// Create connection
$this->conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($this->conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
}
function check_assessment_record($p_id, $a_id) {
$sql = "SELECT * FROM assessments WHERE (pupil_id=$p_id && assessblock_id=$a_id)";
$result = $this->conn->query($sql);
if ($result->num_rows > 0) {
echo '<p>set $de = true</p>';
$de = TRUE;
} else {
echo '<p>set $de = false</p>';
$de = FALSE;
}
return $de;
}
function __destruct() {
$this->conn->close();
}
}
$p_id = 1;
$a_id = 2;
$db = new Database();
$record = $db->check_assessment_record($p_id, $a_id);
var_dump($record);
?>
are you using PDO's correctly?
A call for me would normally look like;
$aResults = array();
$st = $conn->prepare( $sql );
$st->execute();
while ( $row = $st->fetch() ) {
//do something, count, add to array etc.
$aResults[] = $row;
}
// return the results if there is, else returns null
if(!empty($aResults)){return $aResults;}
if you didnt want to put the results into an array you could just check if a column is returned;
$st = $conn->prepare( $sql );
$st->execute();
if(! $st->fetch() ){
echo 'there is no row';
}
Here is the code
function check_assessment_record($p_id, $a_id, $c){
$dataexistsqry="SELECT * FROM assessments WHERE (pupil_id=$p_id && assessblock_id=$a_id)" ;
$resultt = $c->query($dataexistsqry);
if ($resultt->num_rows > 0) {
echo '<p>set $de = true</p>';
$de=TRUE;
}else{
echo '<p>set $de = false</p>';
$de=FALSE;
}
return $de;
$dataexists->close();
}; //end function
You can check the return value using if else condition as
$thereisdata = check_assessment_record($pupil_id, $assessblock_id, $conn);
if($thereisdata){ print_f('%yes data is present%'); }
else{ print_f('% no data is not present %'); }
The reason is , sometime function returning Boolean values only contain the true value and consider false value as null , that's why you are not printing out any result when data is not found.
Hope this will help you. Don't forget to give your review and feedback.

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.

Can't use database connection while inside loop

I am having a problem with mysqli. I am trying to search a database for all people who meet a category. While looping through the results, I want to create an instance of a "Person" class, passing the database connection to the class. This is where the problem starts. Here is my code.
$con = new mysqli($db_host,$db_user,$db_password,$db_name);
if (mysqli_connect_errno())
{
die(mysqli_connect_error()); //There was an error. Print it out and die
}
$sql = "SELECT id FROM users";
$stmt = $con->prepare( $sql );
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
while($stmt->fetch())
{
$person = new Person( $con );
}
$stmt->close();
}
If i move the $person = new Person( $con ); to just after the while loop, it successfully makes an object of the last person. It just won't work when inside the loop. What is the reason for this?
According to error shown, you can't use the same connection until previous result set is in use. In order to make it work, you can do something like this:
$personIDs = array();
while($stmt->fetch())
{
$personIDs[] = $id;
}
$stmt->close();
and than just go through all ids buffered into array:
foreach($personIDs as $id) {
$person = new Person( $con );
}
Or, you can use store_results
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
$stmt->store_results();
while($stmt->fetch())
{
$person = new Person( $con );
}
$stmt->free_result();
$stmt->close();
}

Categories