PHP: Undefined property stdClass, but the property is already exists - php

Below is my class.
class MaterialType {
public $id;
public $name;
function getAllMaterialType() {
$query = "SELECT * FROM material_types";
$result = mysql_query($query);
$arr = array();
while ($row = mysql_fetch_array($result)) {
$arr[] = new MaterialType();
$arr[]->id = $row['m_type_id'];
$arr[]->name = $row['m_type_name'];
}
return $arr;
}
}
The problem is when I create object in an array like above, and display it using foreach,
there are errors that say Undefined property stdClass. I already defined the property that being used, so why these errors appear? Below is the code that I use to
display data.
$materialTypeObj = new MaterialType();
foreach($materialTypeObj->getAllMaterialType() as $mat) {
echo $mat->name;
}

Every time you do $array[] = it inserts a new element in the end of an array. What you need to do is:
class MaterialType {
public $id;
public $name;
function getAllMaterialType() {
$query = "SELECT * FROM material_types";
$result = mysql_query($query);
$arr = array();
while($row = mysql_fetch_array($result)) {
$mat = new MaterialType();
$mat->id = $row['m_type_id'];
$mat->name = $row['m_type_name'];
$arr[] = $mat;
}
return $arr;
}
}

Related

php + mysql query returning only a single row (std class) from class function

Can you tell me why this returns only the last row of my query?
As you see I'm extracting as std class. Also I already tried different approaches like a foreach key=>value inside the while but it does not help. I can't populate $out correctly.
class myclass {
function Query($sql){
$results = $this->db->query($sql);
if (mysqli_num_rows($results)<1){
throw new Exception('NoResults');
}
$out = new stdClass;
while ($r = $results->fetch_object()){
$out = $r;
}
return $out;
$out = null;
}
}
}
---------------
$client = new myclass;
$sql = "SELECT * FROM books";
$q = $client->Query($sql);
print_r($q);
You just need to change those lines:
$out = new stdClass;
while ($r = $results->fetch_object()){
$out = $r;
}
to those ones:
$out = []; // array that will hold all the objects
while ($r = $results->fetch_object()){
array_push($out, $r); // add to the array the current object
}
return $out; //return the array with the objects
You are overwriting $out at every iteration of the while, so you'll have only the last result in the return. You could use an array and append the results (it could be an array of stdClass objects), and then you'll be able to work with it with a simple loop
class myclass {
function Query($sql){
$results = $this->db->query($sql);
if (mysqli_num_rows($results)<1){
throw new Exception('NoResults');
}
//copied this piece of code from #Berto99 answer from this same question
$out = []; // array that will hold all the objects
while ($r = $results->fetch_object()){
array_push($out, $r); // add to the array the current object
}
return $out; //return the array with the objects
}
}
---------------
$client = new myclass;
$sql = "SELECT * FROM books";
$q = $client->Query($sql);
foreach($q as $resultLine){
//do whatever you need to do here
}
Your $r is object. You dont need stdClass. You need to add your objects to $out array.
function Query($sql)
{
$results = $this->db->query($sql);
if (mysqli_num_rows($results) < 1) {
throw new Exception('NoResults');
}
$out = new stdClass;
$i=0;
while ($r = $results->fetch_object()){
$out->{$i} = $r;
$i++
}
return $out;
}

SQL array display in rows without SQL query

I am trying to test a few scripts that I would normally get from an SQL database but for testing offline I am just creating an array.
Here is what I have right now;
$result = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
$resultnum = count($result);
echo "<b>Question 1</b> <br/><br/>";
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$name = $row['name'];
$answer = $row['q1'];
$q1answer = 1;
if($answer == $q1answer) {
echo $name . " got this right! <br/>";
} else {
echo $name . " got this wrong! <br/>";
}
}
}
How can I get this to work the same as though it was getting the array from an SQL query instead of just my array, for some reason I can't find a way to get this to run.
You can wrap the array in an anonymous class. Single uses like this are a main reason they exist.
$result = new class {
private $data = array
(
array("name"=>"Toby", "q1"=>"1"),
array("name"=>"Phelps", "q1"=>"1"),
array("name"=>"Davies", "q1"=>"1"),
array("name"=>"Keith", "q1"=>"1"),
);
private $data_index = 0;
public $num_rows;
public function __construct() {
$this->num_rows = count($this->data);
}
public function fetch_assoc() {
if (isset($this->data[$this->data_index])) {
$index = $this->data_index++;
return $this->data[$index];
}
}
};
Similar to the earlier answer, I propose a class. Here I would actually name the class, and pass the data to the constructor. The iteration over the array can be done with the current and next methods:
class ResultSet {
private $array = [];
public $num_rows = 0;
public function __construct($data) {
$this->array = $data;
$this->num_rows = count($this->array);
}
public function fetch_assoc() {
$val = current($this->array);
next($this->array);
return $val;
}
}
Until there it would be fixed. You would play with the data in the following:
$result = new ResultSet([
["name"=>"Toby", "q1"=>"1"],
["name"=>"Phelps", "q1"=>"1"],
["name"=>"Davies", "q1"=>"1"],
["name"=>"Keith", "q1"=>"1"],
]);
I did not implement support for count($result) as I don't think that is supported on real mysqli result sets either. You get the count via ->num_rows (like you also do).

How can I return multiple objects in a function in php and then display them

public function getdata()
{
$ctrObj = new Country();
$result = $ctrObj->ctrydata($this->table);
if(mysqli_num_rows($result)>0){
while ($row = mysqli_fetch_array($result)) {
return $row;
}
}
}
$ctryObj = new CountryController();
$countries = $ctryObj->getdata();
print_r($countries);
when I print_r($countries); then I can see only one object but if I print that in function mentioned above I found all objects.
You could save results in an array and return it:
public function getdata()
{
$data = []; // Init array
$ctrObj = new Country();
$result = $ctrObj->ctrydata($this->table);
if(mysqli_num_rows($result)>0){
while ($row = mysqli_fetch_array($result)) {
$data[] = $row; // Populate it
}
}
return $data; // Return it
}
Because you return only one result, you can change like this
public function getdata()
{
$ctrObj = new Country();
$result = $ctrObj->ctrydata($this->table);
$rows = [];
if(mysqli_num_rows($result)>0){
while ($row = mysqli_fetch_array($result)) {
$rows[] = $row;
}
}
return $rows;
}
You can yield it :
public function getdata()
{
$ctrObj = new Country();
$result = $ctrObj->ctrydata($this->table);
if(mysqli_num_rows($result)>0){
while ($row = mysqli_fetch_array($result)) {
yield $row;
}
}
}
You would use it like this (with a lot of benefits for memory...) :
$ctryObj = new CountryController();
foreach ($ctryObj->getdata() as $country) {
print_r($country);
}
Edit : I've learned with PDO and never been in contact with mysqli so I've tried to find an equivalent to fetchAll(), and apparently, you have a fetch all function also (http://php.net/manual/fr/mysqli-result.fetch-all.php).
I think your code would look like that :
public function getdata()
{
$ctrObj = new Country();
$result = $ctrObj->ctrydata($this->table);
if (mysqli_num_rows($result) > 0) {
$rows = mysqli_fetch_all($result);
return $rows;
}
}
This looks more efficient that getting all your objects one by one to bind them into an array (as it's done by php natively). Anyway, use yield if you don't want to duplicate the buffer of results (one for mysql side, the other one for php side)

Connect multiple database from any database's data php

I want to connect multiple databases with PHP.
I have table which has a connection parameters, i want to show you codes first.
class someClass {
protected $db, $arrayb;
public function __construct() {
include 'db.php';
$this->db = $db;
$this->arrayb = $arrayb;
}
public function prepareSites() {
$prepareSites = $this->db->prepare("SELECT id FROM sites WHERE site_type='somesites' ORDER BY id ASC");
$prepareSites->execute();
$getCountOpSites = $countOpSites->rowCount();
$prepareSites = $prepareSites->fetchAll(PDO::FETCH_ASSOC);
$arraycount = array();
foreach ($prepareSites as $a) {
$arraycount[] = $a;
}
$arrayb = array();
foreach ($arraycount as $b) {
$arrayb[] = $b["id"];
}
$arrayb;
}
Everything is fine in these codes. $arrayb variable gives me every id, i have no problem with arrays.
But,
public function connectSites() {
$dbarray = array();
$i = 0;
foreach ($this->arrayb as $a) {
$i++;
$conn.$i = $this->db->prepare("SELECT * FROM sites WHERE id='{$a}'");
$conn.$i->execute();
$conn.$i = $conn.$i->fetch(PDO::FETCH_ASSOC);
$asd.$i = $conn.$i["id"];
$host2 = $conn.$i["site_host"];
$name2 = $conn.$i["site_name"];
$user2 = $conn.$i["site_user"];
$pass2 = $conn.$i["site_pass"];
$this->dbop.$i = new PDO('mysql:host='.$host2.';dbname='.$name2.'', ''.$user2.'', ''.$pass2.'');
$this->dbop.$i->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbop.$i->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbarray[] = $this->dbop.$i;
}
return $dbarray;
}
Number of added connection won't be known. That's why i wanted to add $i variable to make different connections as many as i want. But $dbarray variable gives me nothing. And i don't know how to control it if it gives me anything.
Thank You.

MYSQL printing a database record array

function CHECKPENDINGORDERS($con, $oc, $pos){
if(is_resource($con)){
$sql = "SELECT * FROM eats_orders WHERE school_code = '$oc' AND order_status = '$pos'";
$sqlresult = mysql_query($sql);
#$pendingorderrow = mysql_fetch_array($sqlresult);
while($row = mysql_fetch_assoc($sqlresult)){
$a[] = $row;
return $a;
}
}
}
$checkpendingorders = CHECKPENDINGORDERS(MYSQL_LINK, $ordercode, $pendingorderstatus);
print_r($checkpendingorders);
I have the function above me to retrieve db records to and print it out by calling the function. But it is only printing 1 recording but I have multiple records with same ordercode and pendingorderstatus.
You need to return your $a at the end
<?php
function CHECKPENDINGORDERS($con, $oc, $pos){
if(is_resource($con)){
$sql = "SELECT * FROM eats_orders WHERE school_code = '$oc' AND order_status = '$pos'";
$sqlresult = mysql_query($sql);
#$pendingorderrow = mysql_fetch_array($sqlresult);
while($row = mysql_fetch_assoc($sqlresult)){
$a[] = $row;
//return $a; //<---- Not here
}
}
return $a; //<----- Here
}
That is because... You are getting a single row is since you are returning the $a in the first iteration itself.
You need to move your return statement outside of your loop. Once that return statement is reached your function call ends thus terminating your loop.
while($row = mysql_fetch_assoc($sqlresult)){
$a[] = $row;
}
return $a;
To further improve upon your function, your function will throw a E_NOTICE error because you are not defining $a before using it. To solve this just define $a to be an empty string at the top of your function. You can also move the return statement to the end of the array so your function always returns an array, even if it is empty.
function CHECKPENDINGORDERS($con, $oc, $pos){
$a = array();
if(is_resource($con)){
$sql = "SELECT * FROM eats_orders WHERE school_code = '$oc' AND order_status = '$pos'";
$sqlresult = mysql_query($sql);
#$pendingorderrow = mysql_fetch_array($sqlresult);
while($row = mysql_fetch_assoc($sqlresult)){
$a[] = $row;
}
}
return $a;
}

Categories