Object Loop Not Working as Expected - php

I will be honest, I have just started learning objects and I am stuck.
I want to loop through an array of objects and display the name and description for each. But either nothing is displayed or it displays all the names first and then all the descriptions.
I am pulling the information from an API into the object:
// get tasks
foreach($tasksList->items as $task_details) {
$tasks_name[$task_details->id]=$task_details->name;
$tasks_desc[$task_details->id]=$task_details->description;
$tasks_details[$task_details->id]=$task_details->id;
$tasks_progress[$task_details->id]=$task_details->progress;
}
foreach($tasks_name as $taskid=>$my_task_name) {
echo "Task_Name: " . $my_task_name . "</br>";
$task_id = $task_details->id;
foreach($tasks_desc as $taskid1=>$my_task_desc) {
if($taskid==$task_details->id) {
echo "Task_Desc: " . $my_task_desc . "</br>";
}
}
}
Now what I don't understand is: inside the first foreach loop it is like a while loop while i=0, it checks $tasks_name[0], then $tasks_name[1] and so on.
However, I am not sure how to figure out what the id is in the current loop it is on, so I can tell it to only print the description of the current loop and not display all of them.
To be honest I am copying this from another example, but I don't quite understand it. I plan to study objects more, but this is holding me up on my current code:
foreach($tasks_desc as $taskid1=>$my_task_desc)
I understand it is looping through all the $tasks_desc and assigning the value to $my_task_desc but what is the signifigance of $taskid?
Sorry for the newbie questions. :)

This is poorly written. I would move on to another tutorial if it's a tutorial. Either that or the line that task_id is used was left out.
Anyway, tasks_name is an array of tasks indexed by the ID. So the outer loop in the second block loops over the keys/values of that array (the ID is the key, taskid. It was assigned by $task_details->id in the first loop above).
The second loop goes over all of the tasks again, but this time by description task_desc instead of by name. It's trying to find the task_desc with an ID that matches the ID of the task_name before (which would make it the same task).
That's unnecessary, though, because you could just store all of the entries (name, desc, etc.) in one array indexed by the ID instead of storing each in their own array:
(this is the first loop):
foreach($tasksList->items as $task_details) {
$all_tasks[$task_details->id]['name'] = $task_details->name;
$all_tasks[$task_details->id]['desc'] =$task_details->description;
// Don't need the ID again; it's the key
$all_tasks[$task_details->id]['progress'] = $task_details->progress;
}
However, you don't even need to do that, because you can just iterate over tasksList->items when you need to.

There's no need for two loops. To display name and description for each object, one loop is enough:
foreach($tasksList->items as $task_details) {
echo 'name: ', htmlspecialchars($task_details->name);
echo ', description: ', htmlspeciachars($task_details->description);
}
(I also don't understand why you want to store every object field in its own array first?)

Related

How do you set up an array to hold '0's for empty locations so graphs(Highcharts) can format them correctly?

I'm trying to get my Highcharts graph to work. The Reason I'm having so much trouble with it this time is because I have to keep the program adaptable for future changes when it comes to my columns(named issues1 through 12).
The Goal is pretty simple, I just need to grab the issues between hours 1-12 during a certain time period, then create a graph.
My idea Is that I should create a view that organizes the desired information because there is a lot more to that table that I left out, and then create an SQL to organize the data from there. Which I realize might be overkill, but I'm an intern and my supervisor probably did it to help make it simple for me.
There are 4 different places I need to use SQL to make the Table work.
X-Axis
Day shift numbers
Swing shift numbers
Night shift numbers
So for my code The X-Axis, It works fine for just calling in the names.
xAxis: {
categories: [
<?php
foreach ($xAxisresult as $Xrow) {
echo "'" . $Xrow['IssueName'] . "'" . ',';
}
?>
]
I believe the Day/Swing/Grave SQL statements should all be similar so I'm just going to focus on one. But this is where the problem starts with how I have it set up. I tried to run an If statement were I compare the two arrays I have set up and try to match the IssueName Columns.
name: 'Day',
data: [
<?php
foreach ($Dresult as $Drow) {
if ($Xrow['IssueName'] == $Drow['IssueName']){
echo $Drow['Issues'] . ',';
}
else{
echo $Drow['Issues'] . ',';
}
}
You guys can most likely see a lot of whats wrong here. But I need to make a loop or array that will find out that if there is an empty spot in the array and output a 0 so the data stays correct.
Sorry for the wall of Text, I just wanted to give you guys as much information as possible.
To answer your question how to create an array that holds zero values and merge with the data array (I assume).
You can use array_fill to create the array with zeros, and use array_replace to replace with the data array.
$arr = array_fill(0, 10, 0); //[0,0,0,0,0,0,0,0,0,0]
$data = [2 => 15, 5 =>10, 7 => 16]; // your data
$new = array_replace($arr, $data);
var_dump($new); // [0,0,15,0,0,10,0,16,0,0]

Is it possible returning arrays from functions in php for-loop

The 1st for-loop is to retrieve $projSDE_1 which is employee ID and it's a value that changes every loop round.
$projSDE_1_IDs = [];
for($i=0; $i<db_rowcount();$i++)//1st for
{
$projSDE_1=db_get($i,8);
array_push($projSDE_1_IDs,$projSDE_1);
}
$projSDE_1_names = func_GetEmpNameNew($projSDE_1_IDs,$projSDE_1);
Next,the 2nd for-loop is going to retrieve all data and display it.All i need is each row will be able to display $projSDE_1_names by func_GetEmpNameNew($projSDE_1_IDs,$projSDE_1);
for($j=0; $j<db_rowcount();$j++)//2nd for
{
<tr >
<tbody>
<td style='width:5%'>".$no.". </a></td>
<td>".$projID." </td>
<td>".$projClient." </td>";
<td>".$projSDE_1_names." </td>";
</tbody>
</tr>
}//endfor
function to get $projSDE_1_names
function func_GetEmpNameNew($empIDs) {
$names = [];
foreach($empIDs as $empID){
$sqlEmp="select EmpID,LastName2_c from empbasic WHERE EmpID= '".$empID."'";
db_select($sqlEmp);
$rowcount=db_rowcount();
if(db_rowcount()>0){
for($f=0;$f<count($empIDs);$f++){
$empID=db_get($f,0);
$empName=db_get($f,1);
array_push($names, $empName);
}//for
}//if
}//foreach
return $names;
} // function
var_dump($projSDE_1_names); // Display the array to see if you get all the correct data.
The function is work fine and its able returns an array with the employees names..var_dump($projSDE_1_names);
So far this is the result i get - Result.
The list of name that displayed at the top is by
foreach ($projSDE_1_names as $projSDE_1_name) {
echo $projSDE_1_name.'-';
}
I need each name for each row.It listed 10 names from function and its suppose for 10 rows.All help appreciated
You are trying to fix the wrong issue.
Judging from your code, the initial list of values is retrieved from a relational database. The subsequent results are also retrieved from a relational database.
This alone is very wrong (unless the we are talking about 2 separate instances of DBMS which are unable to communicate directly). The right way to retrieve the 2 sets of data is using a JOIN on the data.
But that isn't the only howler in your code.
Repeatedly generating and executing a select statement in a loop is very bad practice. This would be solved by the same approach as the first issue above. However in the event of cases where the reference dataset does not originate on the same relational DBMS there are better ways to solve the problem. I would make a suggestion, but the db_ functions in your code are not standard PHP functions. The behaviour exposed in your code seems like a very cumbersome and limiting interface. Using mysqli you could simply....
function func_GetEmpNameNew($empIDs) {
global $db_handle;
$sqlEmp="select EmpID,LastName2_c from empbasic WHERE EmpID IN ("
. implode(",", $empID) // assuming the inputs are trusted and integer values
")";
$res=mysqli_query($db_handle, $sqlEmp);
return mysqli_fetch_all($res, MYSQLI_ASSOC);
}
As a side note you are using the order in which the data is returned in the orinal query as a means of indexing the result sets. As long as you are retrieving a single row each time, the data will matchup - but your code might retrieve zero, one or more than one row each time - again the solution is to run one query with a join. If you need to run queries against aseperate datasources, then index the array by a primary key attribute from the original dataset.

Grouping array values by similar

i'm making a grocerylist system that takes into account amount of recipies you throw at it.
based on that, it combines values and outputs a grocerylist for you.
i'm looping a mysql query and create arrays like this:
foreach sql loop{
$ingredients = array(
"id"=>array($id),
"name"=>array($name),
"amount"=>array($amount),
"unit"=>array($unit)
);
foreach ($ingredienser as $key => $value) {
foreach ($value as $index => $v) {
echo $key."=";
echo $v;
echo "<br><hr>";
}
}
}
That whole ordeal outputs a list like this if i throw 1 recipe at it:
id=150
name=Cherrytomater
amount=300
unit=Gram
id=151
name=Kyllingfilet
amount=4
unit=Stykk
if i throw 2 recipies it throws the next recipe under it.
However, i need it to do a certain set of things.
merge values if the name is similar
ignore the above merge if unit is different (its a shopping list after all)
output a combined list of ingredients based on the recipies and amount of recipies i throw at it.
To further explain; the sql equivalent of what im trying to achieve is :
$dupe = "2" //amount of similar recipies
SELECT i.id, i.ingred, r.enhet, r.id, SUM(r.mengde * $dupe) total, r.enhet FROM oppskriftingred r left join ingrediens i on i.id = r.ingrediens WHERE r.oppskriftid IN $vars2 GROUP BY i.ingred, r.enhet ORDER BY i.ingred
However, the sql approach wont work as the SUM doesn't differentiate between different recipies.. if $ dupe is 4 for one recipe and 2 for another, its 4 for both.
So how can i do this in php with arrays? Any help is greatly appreciated!
Your "this is what I need list" has one problematic point:
1. merge value if the name is SIMILAR
The rest is quite simple. You have an array of ingerdients $ingredients. You need to loop through this and compare every entry to a result array, to figure out if your points 2 and 1 match it to a existing or new entry. I would give the new array a key, that makes matching easy. Let's say the unit and the name as a string: 'Gram-Cherrytomater'
$result = array();
foreach ($ingerdients as $item) {
$newKey = $item['unit'].'-'.$item['name'];
if (isset($result[$newKey]) {
// add amount to existing item
$result[$newKey]['amount'] += $item['amount'];
} else {
// add new item
$result[$newKey] = $item;
}
}
// now loop trough the result and display whatever you want
The problem is with the SIMILAR thing. I do not know, how you want to compare to strings that are similar. You should do this when getting the $newKey. Do something with $item['name'] to make it "similar".
You could use some php function like similar_text(), levenshtein() or soundex(). I do not know how good this works for your language (Danish?).

Editing the object returned by $wpdb->get_results(SQL)

We have a nasty database call using the Wordpress function $wpdb->get_results(SQL).
After receiving the result in PHP, we need to make a few changes to the result.
So can anyone tell me how I can:
1) Remove specific rows from the get_results() returned object.
2) Change the values of the specific columns in specific rows in the returned object.
I.e. if the object returned is $nastyData, we need to:
1) Remove specific rows from $nastyData
2) Change the value of specific columns in specific rows in $nastyData, for example $nastyData->name for a specific row.
Any ideas?
I have thought about makeing get_results() return the data as an array, but that will create problems in other places in our code (where the code expects to receive an object).
Thanks,
Mads
To start with, your "Nasty database call" should be optimized to be less nasty. More specifically, only query the results you want so that you don't have to remove stuff afterwords. This is the best solution.
If you insist on trying to modify the objects, this is a workaround. According to the documentation, when returning objects, they are returned in one of two ways:
OBJECT - result will be output as a numerically indexed array of row objects.
OBJECT_K - result will be output as an associative array of row objects, using first column's values as keys (duplicates will be discarded).
So, knowing that the result is an array of objects, we can get to each individual instance using a foreach construct:
$results = $wpdb->get_results( $nastySQL );
foreach($results as $index => $result)
{
// Change name column to FirstName using copy and delete
$tmp = $result->name;
unset($result->name);
$result->FirstName = $tmp;
// Remove specific row
if( $result->name == "Tom")
{
unset($results[$index]);
}
}
Below code will replace the value coming from specific field of database table, if name field has value like Reo and you want to replace it with other name like John then you can to do this via below code
$results = $wpdb->get_results( $nastySQL );
foreach($results as $key => $value){
$results[$key]->name= 'John';
}
return $results;

PHP - associative array - blank row being added

I am trying to build Dynamic UI by getting data from DB using CodeIgniter but facing problem in constructing array.
Requirement:
Get parent menu items in an array. Then get child item corresponding to each parent item.
Code to get data for parent element::
$data['menu'] = $this->Menu->get_admin_menu_data();
This gives me 3 records
echo "before loop menu" . count($data['menu']) . "</br>"; //prints 3
Now I run a foreach loop for each parent item to retrieve it's child item
foreach($data['menu'] as $menu){
$data['menu']['menu_item'] = $this->Menu->get_admin_menu_item_data($menu->ad_menu_id);
echo "inside loop menu " . count($data['menu']) . "</br>"; //prints 4
}
As soon as I do this the count of menu increases to 4 resulting in error in UI.
I am new to PHP so now sure what is the best way to create a structure to hold this type of data.
Please help!!!!
If $data['menu'] contains 3 key/value pairs, but $data['menu']['menu_item'] is not set, your statement
$data['menu']['menu_item']
= $this->Menu->get_admin_menu_item_data($menu->ad_menu_id);
sets just this.
Thus count( $data['menu'] ) returns 4 elements afterwards - including the newly added 'menu_item' key.
I don't know CodeIgniter, but overwriting a static variable
$data['menu']['menu_item'] = "someting"
never makes sense. Where do you really want to store the result of
$this->Menu->get_admin_menu_item_data($menu->ad_menu_id);
? You can and should check the content of a variable using var_dump.

Categories