Can I put new values in array inide foreach? - php

I have a foreach loop, in which I loop through the array. I want to add elements as I go through it and have new ones go through it as well.
Now with this code it only does the iterations that I have in the array at the beginning (1 in this case).
Can somebody help me
Thanks
public static function getDirectoriesChilds($id_parent, $parents_array) {
$session_client = Client::getSessionClient();
array_push($parents_array, $id_parent);
$parents_array = array_unique($parents_array);
foreach ($parents_array as $element) {
$childs = Directory::where('id_parent' , '=', $element)->get();
foreach ($childs as $child) {
if ($child->deleted == Controller::DISABLED) {
array_push($parents_array, $child->id);
$parents_array = array_unique($parents_array);
}
}
}
return $parents_array;
}

If changes foreach to for works.
for($i=0; $i<count($parents_array); $i++){

Related

PHP Serialized Data output inside foreach loop

I've been stuck on this for like 2 days, and I know it's much more simpler than I think it is..
I have a foreach loop that goes like this.
foreach($appointments as $appointment){
$list = $appointment['techs']
}
The $appointment['techs']; comes out of the database like this.
a:2:{i:0;s:1:"1";i:1;s:2:"12";}
My question is, how to I get loop through appointments and then show the users that are assigned to each appointment...
The desired output should look like this,
{ resource : 1, event : 1},{ resource : 12, event : 1}
I've literally tried everything! Any help would be greatly appreciated.
$array = [];
$string = 'a:2:{i:0;s:1:"1";i:1;s:2:"12";}';
$arr = (unserialize($string));
foreach ($arr as $item){
array_push($array, json_encode(['resource'=> $item, 'event'=>1]));
}
$i = 0;
$numItems = count($array);
foreach ($array as $item) {
if (++$i === $numItems) {
echo $item;
}
else{
echo $item.',';
}
}
// Output: {"resource":"1","event":1},{"resource":"12","event":1}
The PHP command unserialize it's what you are looking for.
foreach($appointments as $appointment){
$list = unserialize($appointment['techs']);
}

foreach leaves out the very first value

I am processing a foreach(first) which gives the full array in the data, when I make another foreach(second) and pass the first foreach into second foreach the first value of the first foreach never appears in the second foreach. Does anyone have any idea why the foreach behaves this way? is there a solution for this?
I tried it this way no luck
$userIdsPerRoom = chatRoomUsersId($_SESSION['currentRoomID']);
foreach ($userIdsPerRoom as $value) {
$list[] =$value['UserID'];
}
foreach ($list as $value) {
$userInfo = chatRoomUsersEmail($value);
foreach ($userInfo as $info) {
echo $info['userEmail'];
}
}
echo count($list); ///gives the full list
}
I noticed it with this code
$userIdsPerRoom = chatRoomUsersId($_SESSION['currentRoomID']); //return an array of intergers with five values example array(1,2,3,4,5)
foreach ($userIdsPerRoom as $value){
$userInfo = chatRoomUsersEmail($value['UserID']);
foreach ($userInfo as $info){
echo $info['userEmail']; /// I only get four values example array(b,c,d,e)
}
}

Dynamic add to current foreach array

I have a loop that needs to go through each item. So naturally a foreach loop seems like the best idea. However, I need to add an element to the array as it iterates. I tried the following without any luck.
foreach ($allitems as $item) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
I found out the foreach loops seem to use a referenced copy of the array, so editing the array does not register in the loop.
A workaround is to use the older styled while loops as follows:
while (list($key, $item) = each($allitems)) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
Clearly a foreach loop would be nicer and more efficient. Is it possible? Or is the while structure the best possible solution.
Yeah, it is possible:
foreach ($allitems as &$item) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
According to the docs, you need to pass a reference (using the & in front if $item)
More concrete example:
<?php
$allitems = array(1,2,3,4);
foreach ($allitems as &$item) {
echo $item."\n";
if ($item == 2) {
$allitems[] = "Blah";
}
}
?>
This outputs (using php from commandline)
1
2
3
4
Blah
It seems like an ordinary for loop would be best for this:
for ($i = 0; $i < count($array); $i++) {
// Do some stuff here that calculates $value from $array[$i]
if ($value === true) {
$array[] = "New Element";
}
}
You could do foreach...like this....
But it adds more code...so its not any better than your while loop..
foreach($array as $val){
if($val=="check"){$append[]="New Item";}
}
$array = array_merge($array, $append);
Of course, if you want your structure maintained..then rather use array_push

PHP Nested loops where values are the key to the next level of the array

I'm relatively new to PHP and I hope you can help me solve my problem. I am selecting out data from a database into an array for timekeeping. Ultimately, I would like to calculate the total number of hours spent on a project for a given customer.
Here is the code to populate a multi-dimensional array:
...
foreach ($record as $data) {
$mArray = array();
$name = $data['user'];
$customer = $data['customer'];
$project = $data['project'];
$hours = $data['hours'];
$mArray[$name][$customer][$project] += $hours;
}
...
I would now like to iterate over $mArray to generate an xml file like this:
...
foreach ($mArray as $username) {
foreach ($mArray[$username] as $customerName) {
foreach ($mArray[$username][$customerName] as $project ) {
echo '<'.$username.'><'.$customerName.'><'.$project.'><hours>'.
$mArray[$username][$customerName][$project].'</hours></'.$project.'>
</'.$customerName.'></'.$username.'>';
}
}
}
This nested foreach doesn't work. Can someone give me a couple of tips on how to traverse this structure? Thank you for reading!
UPDATE:
Based on the comments I've received so far (and THANK YOU TO ALL), I have:
foreach ($mArray as $userKey => $username) {
foreach ($mArray[$userKey] as $customerKey => $customerName) {
foreach ($mArray[$userKey][$customerKey] as $projectKey => $projectName) {
echo '<name>'.$userKey.'</name>';
echo "\n";
echo '<customerName>'.$customerKey.'</customerName>';
echo "\n";
echo '<projectName>'.$projectKey.'</projectName>';
echo "\n";
echo '<hours>'.$mArray[$userKey][$customerKey][$projectKey].'</hours>';
echo "\n";
}
}
}
This is now only providing a single iteration (one row of data).
Foreach syntax is foreach($array as $value). You're trying to use those values as array keys, but they're not values - they're the child arrays. What you want is either:
foreach($mArray as $username) {
foreach($username as ...)
or
foreach($mArray as $key => $user) {
foreach($mArray[$key] as ...)

in foreach, isLastItem() exists?

Using a regular for loop, it's possible to comapred the current index with the last to tell if I'm in the last iteration of the loop. Is there a similar thing when using foreach? I mean something like this.
foreach($array as $item){
//do stuff
//then check if we're in the last iteration of the loop
$last_iteration = islast(); //boolean true/false
}
If not, is there at least a way to know the current index of the current iteration like $iteration = 5, so I can manually compare it to the length of the $array?
The counter method is probably the easiest.
$i = count($array);
foreach($array as $item){
//do stuff
//then check if we're in the last iteration of the loop
$last_iteration = !(--$i); //boolean true/false
}
You can use a combination of SPL’s ArrayIterator and CachingIterator class to have a hasNext method:
$iter = new CachingIterator(new ArrayIterator($arr));
foreach ($iter as $value) {
$last_iteration = !$iter->hasNext();
}
Here are a few methods for this;
$items = ["Bhir", "Ekky", null, "Uych", "foo"=>"bar"];
$values = array_values($items);
// Bhir, Ekky, Uych, bar
foreach ($values as $i => $item) {
print("$item");
$next = isset($values[$i + 1]);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
foreach ($values as $i => $item) {
print("$item");
$next = array_key_exists($i + 1, $values);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
$i = count($values);
foreach ($items as $item) {
print("$item");
$next = !!(--$i);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
$items = new \CachingIterator(new \ArrayIterator($items));
foreach ($items as $item) {
print("$item");
$next = $items->hasNext();
if ($next) {
print(", ");
}
}
No, you need to have a counter and know the amount of items in the list. You can use end() to get the last item in an array and see if it matches the current value in your foreach.
If you know that the values of the array will always be unique, you can compare the current $item to end($array) to know if you're at the last item yet. Otherwise, no, you need a counter.
You can get the key and the value in foreach() like this:
foreach($array as $key=>$value) { ... }
Alternatively, you could do a count() of the array so you know how many items there are and have an incrementing counter so that you know when you've reached the last item.
end($array);
$lastKey = key($array);
foreach($array as $key => $value) {
if ($key === $lastKey) {
// do something endish
}
}
The valid() method says if the ArrayIterator object has more elements.
See:
$arr = array("Banana","Abacaxi","Abacate","Morango");
$iter = new ArrayIterator($arr);
while($iter->valid()){
echo $iter->key()." - ".$iter->current()."<br/>";
$iter->next();
}

Categories