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).
Related
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)
I've written code that reads data from a cURL source which then processes it to extract records of data.
Each record becomes an instance of an object with several variables set from the data. A function extracts all the data and returns an array of objects.
The problem is that all of the objects have the same value which is the last record to be read from the source data.
After some testing I realize this is a reference problem. Data is read from the source and then assigned to an object which is then added to the array. The same object is reused in a loop that cycles through all the records in the source. Whenever this object is updated all previous values in the objects in the array are also reset to the newest value as they continue to reference the object when it is updated.
How can I make all the values independent?
function get_object_array () {
//reads raw data from cRUL source, returns array of objects
//array to hold objects
obj_arr = [];
//raw data has been split into array called $record, one element for each object
//loops through $record array
foreach ($record as $rec) {
//splits $rec into array of data called $data
//creates new object, but problem here as this object
//is being referenced by all values so last value
//changes all previous objects in array
$obj = new SaleItem();
//populates object with record data array
$obj->set_data($data);
//add object to array
$obj_arr [] = $obj;
}
return $obj_arr;
}
Update: Here is the function to set the data:
function set_data (array $arr) {
global $order_num, $name, $price, $cprice, $cheapest, $category;
try {
$order_num = (int)$arr[0];
$name = $arr[1];
$price = (float)$arr[2];
$cprice = (float)$arr[3];
$cheapest = $this->$price <= $this->$cprice ? true : false;
$category = $arr[5];
return true;
}
catch (Exception $ex) {
echo $ex;
return false;
}
}
Update: Full class code:
class SaleItem {
public $order_num = 12;
public $name = "";
public $price = 3.4;
public $cprice = 5.6;
public $cheapest = true;
public $category = "No Category";
function set_data (array $arr) {
try {
$this->order_num = (int)$arr[0];
$this->name = $arr[1];
$this->price = (float)$arr[2];
$this->cprice = (float)$arr[3];
$this->cheapest = $price <= $cprice ? true : false;
$this->category = $arr[5];
return true;
}
catch (Exception $ex) {
echo $ex;
return false;
}
}
function get_data () {
echo $this->order_num . ' num<br/>';
echo $this->name . ' name<br/>';
echo $this->price . ' price<br/>';
echo $this->cprice . ' cprice<br/>';
echo $this->cheapest . ' cheapest<br/>';
echo $this->category . ' category<br/>';
echo '<br/>';
}
}//end SaleItem class
You are using global variables instead of members. Remove
global $order_num, $name, $price, $cprice, $cheapest, $category;
From the function and preface each assignment with $this->
$this->order_num = (int)$arr[0];
$this->name = $arr[1];
$this->price = (float)$arr[2];
$this->cprice = (float)$arr[3];
$this->cheapest = $this->price <= $this->cprice;
$this->category = $arr[5];
I have got this code:
function retrieve_answers($array = array(), $id = null)
{
include(root_path . '\config.php');
if($id == null)
{
$id = $this->question_id;
}
$query = mysqli_query($link, "SELECT * FROM `answers` WHERE `question_id`='$id'");
if(!mysqli_num_rows($query))
{
throw new Exception('Question not found.');
}
/* - Retrieves the answer rows
- Loops through the array
- Indexes the array and assigns the answerID to the index */
else
{
while($result = mysqli_fetch_array($query))
{
for($i=0;$i<mysqli_num_rows($query);$i++)
{
$array[$i] = $result["id"];
}
}
}
}
Which is a part of a class.
What am I trying to do?
I am trying to accept an array as a parameter, and assign values to the array, the values are to be answerIDs which are linked to the question.
The test.php file is here:
<?php
define('root_path', realpath(dirname(__FILE__)));
include(root_path . '\config.php');
require_once(root_path . '\includes\question.class.php');
$q = new Question(3);
$array = array();
$q->retrieve_answers($array);
var_dump($array);
?>
What happens?
When I try to debug by dumping the array, it shows that the array contains nothing:
array(0) { }
I tried to execute the MySQL result through the class to debug, and it does succeed to retrieve the answer IDs, so I'm pretty positive the issue is in the array.
I would happy to get assistance, thanks in advance.
return value in a function like this
function retrieve_answers($array = array(), $id = null)
{
include(root_path . '\config.php');
if($id == null)
{
$id = $this->question_id;
}
$query = mysqli_query($link, "SELECT * FROM `answers` WHERE `question_id`='$id'");
if(!mysqli_num_rows($query))
{
throw new Exception('Question not found.');
}
/* - Retrieves the answer rows
- Loops through the array
- Indexes the array and assigns the answerID to the index */
else
{
$i = 0;
while($result = mysqli_fetch_array($query))
{
$array[$i] = $result["id"];
$i++;
}
return $array;
}
}
and then get it as
$arr = $q->retrieve_answers($array);
var_dump($arr);
So basically I have an array, and I have a function that will return an array value, but it is not returning anything.
$skills = array("Attack");
$i = 0;
$hs = file_get_contents("localhost/player=".$_GET["player"]);
foreach($skills as $value) {
$hs[$i] = explode(",",$hs[$i]);
$stats[$value]["rank"] = $hs[$i][0];
$stats[$value]["level"] = $hs[$i][1];
$stats[$value]["xp"] = $hs[$i][2];
$i++;
}
function getSkill($skill) {
//echo $skill;
return $stats[$skill]["level"];
}
I have tried getSkill("Attack"); and it doesn't work;
but if I do echo $stats["Attack"]["level"]; it works fine.
You don't pass the $stats array to your function so it can't know what is in it.
function getSkill($stats, $skill) {
//echo $skill;
return $stats[$skill]["level"];
}
and call it with getSkill($stats,"Attack");
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;
}
}