Undefined offset error when iterating array after removing elements from it - php

I receive the following error message:
Undefined offset: 1
It points to this block of code:
$nbrProgrammingsRemoved = 0;
for($i = 0; $i<count($this->products); $i++){
if((($this->products[$i])->id)==$id){
array_splice($this->products, $i, 1);
for($j = 0; $j<count($this->programming); $j++){
/*ERROR LINE*/ if((($this->programming[$j]->out_prod_id)==$id) || (($this->programming[$j]->in_prod_id)==$id)){
$nbrProgrammingsRemoved++;
array_splice($this->programming, $j, 1);
}
}
return true;
}
}
return false;
Specifically, the error points to the innermost if-statement. (The one with "||" in it).
Now, important to note is that this error does not always occur. It only ever happens after the following code has been run:
foreach ($this->programming as $key => &$prog) {
if($prog->in_prod_id == $in_prod_id){
if($prog->in_index == $in_index){
unset($this->programming[$key]);
}
}
}
The purpose of this code is to iterate through my objects in my array and remove those associated with a certain ID. This does appear to work since the output on my website is as expected. It's only when I, after doing this, attempt to execute the first code-block that my error occurs.
I've tried troubleshooting this for a while now, but without success. Any ideas? Any more information that you need me to post?
Edit: For further clarification, if needed, the 1st code block iterates through an array to remove a single element of a specified ID. The 2nd code block iterates through another array and removes several elements.

As far as I understand, you have an array with indexes comming in a sequence:
$programming = array(
0 => ...,
1 => ...,
2 => ...,
);
At some point you unset one element, so you array looks like this:
$programming = array(
0 => ...,
2 => ...,
);
And then you're using a for loop to iterate over all numbers from 0 up to N-1 (0, 1, 2, 3, 4 ... to be precise) presuming that all indexes are filled.
I think the best solution is to use a foreach loop in this case as it will care about indexes automatically and bypass deleted items.

Related

If Statement with Foreach not iterating through foreach

I am having an issue with my code - fairly new to PHP so any pointers would be appreciated.
I have the following code
foreach(findCustomAlerts($customerid) as $key=>$value){
echo "ID : ".$rifdid = $value['Catid']."<br>";
echo "Visits required per day : ".$visitsneeded= $value['Visits required']."<br>";
}
foreach(getTodaysVisits($device_id) as $rfid){
foreach($rfid as $key=> $read){
if($key ==$rifdid && $read < $visitsneeded) {
echo"<br>". $key." has not visited enough";
}
}
}
But it is not iterating through the foreach - it is only picking up the first values and then stopping :
ID: 1005
Visits required per day : 3
ID : 2089
Visits required per day : 5
2089 has not visited enough
This is the array that the foreach should be iterating through:
Array
(
[rfid_id] => Array
(
[2089] => 1
[1005] => 3
)
)
I have tried putting a variable in to count the iterations like so :
$i = 0;
foreach(getTodaysVisits($device_id) as $rfid){
foreach($rfid as $key[$i]=> $read){
if($key[$i] ==$rifdid && $read < $visitsneeded) {
echo"<br>". $key[$i]." has not visited enough";
$i++;
}
}
}
But it gives me the following errors :
Warning: Cannot use a scalar value as an array
Notice: Trying to access array offset on value of type int in
So not sure what the best course of action is, any advice greatly appreciated.
This looks like the structure that you are receiving from findCustomAlerts($customerid) in the first for-each loop is not what you are expecting, however the warnings don't give line numbers so I could be wrong.
In your code you have a $key that goes unused, then a $value that you treat as an array.
The warning message you get tells us that you can't use a scalar (or singular) value type as an array. We then get a notice telling us that when we try to use it as an array, either the offset 'Catid' or 'Visits required' is unavailable, likely due to the same reason. I suspect $value is more likely of type integer based on the array example you've shown (1,3).
Run a var_dump() on the output of the findCustomAlerts function and I think you'll understand the issue better.

Sum columns and remove original indexes from multi-dimensional array [duplicate]

This question already has answers here:
Group array data on one column and sum data from another column
(5 answers)
Closed 5 months ago.
I have a php array like this:
[
['url_id' => 2191238, 'time_spent' => 41],
['url_id' => 2191606, 'time_spent' => 215],
['url_id' => 2191606, 'time_spent' => 25]
]
How to get the SUM of time_spent based on group by url_id (using array_count_values?)?
Let's pretend that $array contains our data. We will go through the array and continually add the time_spent to another array keyed by url_id.
$ts_by_url = array();
foreach($array as $data) {
if(!array_key_exists($data['url_id'], $ts_by_url))
$ts_by_url[ $data['url_id'] ] = 0;
$ts_by_url[ $data['url_id'] ] += $data['time_spent'];
}
$ts_by_url should now contain:
2191238 => 41
2191606 => 240 // == 215 + 25
The OP posted an interesting problem, but the suggestion of using array_count_values() was not applicable; the function does not sum array values but counts their frequency. The answer of #marcocassisa works but is insufficient because of the unfortunate emission of E_NOTICES, albeit unrelated to any math issue. (An undefined variable is unset and thus of NULL value, but in a math context it will temporarily be coerced into a value of zero.) Modern PHP discourages the use of undefined variables by intentionally raising notices when code utilizes them, with one exception starting with PHP 5.1: a statement consisting of only an undefined variable; see here.
To rectify the aforementioned solution, one might use two foreach loops, one to set the index keys and initialize the array elements while the other would perform the summing of values, as follows:
<?php
// set keys and initialize
foreach($arr as $data) {
$its_by_url[ $data["url_id"] ] = 0;
}
// now can sum values by url id number:
foreach($arr as $data) {
$its_by_url[ $data["url_id"] ] += $data["time_spent"];
}
see demo.
While satisfactory, this solution lacks elegance. Attempting to combine the two foreach loops into one, will negatively impact the second element, as it gets defined and then needlessly redefined. One could code per the answer of #Charles and create the url id numbered index if it doesn't already exist. Or, you could test to see if it is set, as follows:
<?php
foreach($arr as $data) {
if ( !isset( $its_by_url[ $data["url_id"] ] ) ) {
$its_by_url[ $data["url_id"] ] = 0;
}
$its_by_url[ $data["url_id"] ] += $data["time_spent"];
}
see demo
Note: if an array element were defined as null, then isset() would return false while array_key_exists() would return true. Per, Ilia Alshanetsky
... if your application does not need to distinguish between an
array key that does not exist and one whose value happens to be
NULL you should use isset() because it happens to be a little
faster.
Why not a simpler
$ts_by_url = array();
foreach($array as $data) {
$ts_by_url[ $data['url_id'] ] += $data['time_spent'];
}

Replace values of an array with another array in php

So, i am trying to display a chart where the profit and payout is rendering on a chart. If there is a no profit and payout value in chart then it should show 0.
I have an array with values of profit and payout with hour. Now i want to replace that array with an existing array of 0 values.
Here is my code
$a1=array();
for($i=0,$i<=24,$i++){
$a1['hour']=$i;
$a1['payout']='0';
$a1['profit']='0';
}
$a2=array();
$a2['hour']='2';
$a2['profit']='300';
$a2['payout']='100';
print_r(array_replace($a1,$a2));
There is something wrong with this code. Can any1 tell me what i am doing wrong?
<?php
// Initial array
$a1=array();
for($i=0;$i<=24;$i++){
// Use hour as index of array, if you use $a2[] = array(), it works
// But problem is when you change hours, lets say 12-24, if will cause problem
$a1[$i] = array(
'hour'=> $i,
'payout'=> 0,
'profit'=> 0
);
}
// Array from database
$a2=array();
$a2[] = array(
'hour'=> 2,
'payout'=> 300,
'profit'=> 100
);
$a2[] = array(
'hour'=> 5,
'payout'=> 3500,
'profit'=> 1200
);
echo '<pre>';
// Loop through second array and check if it is there in first one.
foreach( $a2 as $item) {
if(isset($a1[$item['hour']])) {
// Replace the values
$a1[$item['hour']] = $item;
}
}
print_r($a1);
?>
You are using for loop in wrong way, SyntaxError
for($i=0;$i<=24;$i++){ // <= See semi colons
}
First of all your For Loop isn't correct ! you must replace the "," with ";"
You are having a syntax error in your program.
Your working program should look something like this
$a1=array();
for($i=0;$i<=24;$i++){
$a1['hour']=$i;
$a1['payout']='0';
$a1['profit']='0';
}
$a2=array();
$a2['hour']='2';
$a2['profit']='300';
$a2['payout']='100';
print_r(array_replace($a1,$a2));
Hope this helps!

PHP foreach() is amending the array

The following code which is displaying a value from within an array is presenting different results when wrapped in a foreach() as opposed to when I use a simple for-loop. The for-loop is presenting the correct data but the foreach() appears to be amending the input array with every iteration.
$arr = array_merge($arr1, $arr2);
for ($x = 0; $x < count($arr); $x++) {
echo $arr[90]['circread_value'];
}
foreach ($arr as $unused) {
echo $arr[90]['circread_value'];
}
The output from the for-loop is the same value over and over again (as expected):
1382429.00
1382429.00
1382429.00
1382429.00
...
The output from the foreach() shows that the 91st element in the array is changing with each iteration:
56256.00
45652.00
50726.00
317896.00
...
How can this be?
Note: I know the code above is contrived (obviously within the foreach() I'm actually wanting to do further processing and refer to each element of the array that I'm iterating through, not just look at the 91st element.) I have simply pared back the code to something simple (as part of my debugging, as much as for posting here!)
Some further information:
$arr has been created by array_merge'ing two 91-element arrays to create a 182 element array.
The behaviour I see is only happening for the 91st element - if I echo out $arr[89]['circread_value'] or $arr[91]['circread_value'], I get consistent values from the foreach() too.
The (seemingly random) values that I see in the foreach() are actually values from other elements in the array (the array as it looks prior to beginning the foreach)
The input arrays ($arr1 and $arr2) can be found here: http://pastebin.com/wQN8XXu2
Thanks for any insight. Don't hesitate to ask for further information.
foreach modifies the internal array pointer, for doesn't, because it expects you to supply an integer offset, as evidenced here http://us3.php.net/manual/en/control-structures.foreach.php
"As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior."
There is something wrong with your code brother.
I've just tested this:
$arr = array(
0 => array('blah' => 123.42),
1 => array('blah' => 5488.87),
90 => array('blah' => 669874.923)
);
for ($x = 0; $x < count($arr); $x++) {
echo $arr[90]['blah'] . PHP_EOL;
}
foreach ($arr as $unused) {
echo $arr[90]['blah'] . PHP_EOL;
}
And it outputs fine:
669874.923
669874.923
669874.923
669874.923
669874.923
669874.923
Do you mind showing us a little more of your code?
Problem found. That 91st element of the array was actually a reference to the array. The foreach was then using the same variable name (reference to the same array - named $unused in the example snippet I gave in the question) so both were looking at the same array.
We noticed the "&" in the array dump after posting it on here for you guys, so StackOverflow has helped our debug process... thanks for everyone's input.

How do I reindex an array after using unset()?

I'm having a little trouble with losing my array order after using unset(). This is the code I am using.
$id = $_GET['id'];
for ($i = 0; $i < count($my_array); $i++) {
if ($my_array[$i] == $id) {
unset($my_array[$i]);
}
}
Assume that $my_array has 4 items and $my_array[1] is equal to $id. After I unset that, I loop on $my_array and I get an Undefined Offset: 1 error. With print_r($my_array), I get $my_array[0], $my_array[2], and $my_array[3].
I understand perfectly why that's happening. Is there a way to re-index the array so that item 2 'drops' to item 1, and and the rest of the items respectively to the end of the array?
Something like reindex($my_array) would be sweet. I know I could run another for loop with a new array and transfer them manually, but a one step solution would be awesome. I just couldn't find anything anywhere.
Call array_values to reindex the array.
I just discovered you can also do a
array_splice($ar, 0, 0);
That does the re-indexing inplace, so you don't end up with a copy of the original array.

Categories