Undefined offset while printing multidimensional array in PHP - php

I have a multidimensional array in PHP which looks like this
$names_of_tragedies=array(
$row["Character_code"]=>array(
($another_counter)=>$temp_string)
)
I am creating an array called $names_of_tragedies.
It has several subsets or sub-arrays, with each sub-array being named $row["Character_code"] and the "Character_Code" is different for each sub-array.
Each of these sub-arrays has another array within, with the header field being called $another_counter. $another_counter is a numerical value, so it ranges from 1 to a fixed number.
I am entering the data correctly. I have checked it. The problem is with printing it.
Whereas I can access every sub-array $row["Character_code"], I can access only the final sub-sub-array $another_counter.
For e.g., if I have a sub-array where $row["Character_code"]='Prometheus' and 'Prometheus' has only one sub-sub-array [1] whose value is 'APB', I can print it, using
echo $names_of_tragedies[$row["Character_code"]][$another_counter];
The problem occurs when a sub-sub-array has multiple values.
For e.g., if I have a sub-array where $row["Character_code"]='Antigone' and 'Antigone' has 5 sub-sub-arrays [1],[2],[3],[4] and [5] whose value is
[1]='ASAT',[2]='SANTIGONE',[3]='SOTK',[4]='SOAC' and [5]='EPW',
then creating a loop where the value of the variable $another_counter changes from 1 to 5, and using $row["Character_code"]='Antigone,
echo $names_of_tragedies[$row["Character_code"]][$another_counter];
only successfully returns the value of EPW. For every other occasion when $another_counter=1,2,3 or 4,
it says
Undefined offset: 1 or Undefined offset: 2 or Undefined offset: 3 or
Undefined offset: 4
. It is only when I reach the final value, 5, that it displays the data, 'EPW'.
Somehow the counter seems to be set to the last or only value. How do I print the earlier sub-sub-arrays?

The code you have shown where you fill this array, seems to overwrite the array under the key $row["Character_code"] every single time, instead of actually adding items to it.
Those four initial lines should probably rather be something like this:
$names_of_tragedies[$row["Character_code"]][$another_counter] = $temp_string;
That will add all the $temp_strings to the array that is $names_of_tragedies[$row["Character_code"]], using $another_counter as the key for each item.

Related

Codeigniter, array in session, change the value of array in session in a specific key

I have a variable in session that contains array of numbers. I want to change a specific number inside that variable.
My session:
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => true,
// 20 slots, the counting starts from 0, the last slot's position
// is 19.
'slots_id' => array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
);
So, slots_id is the variable that i want to access. I need to change the last number, it.In my controller i have the following.
$this->session->set_userdata('slots_id'[19], 100);
Here i'm trying to set the last slot's value to 100. But the "[19]" that i put there causes error.
A PHP Error was encountered Severity: Notice Message: Uninitialized string offset: 19
Google did not help me in my current situation, thank you for your time.
Two ways around your problem:
$this->session->set_userdata('slots_id'[19], 100); is not attempting to assign a value of 100 to the array element on index 19 for the $slots_id array. It's trying to set a value of 100 as the 20th character (index 19) of the 'slots_id' string, which goes out of bounds.
You may try:
$this->session->set_userdata('slots_id[19]', 100);
Or even better, remove the full element from session, update it and reset it:
$aux = $this->session->userdata('slots_id');
$aux[19] = 100;
$this->session->unset_userdata('slots_id');
$this->session->set_userdata('slots_id', $aux);
it's a bit more code, but my advice would be to always replace session data rather than update it on the fly.
Uninitialized string offset errors in PHP have a vast amount of documentation around them. You are getting this error because you are not referencing index 19 of an Array, you're referencing it of a string, which is exactly what 'slots_id' is in this instance. 'slots_id' is 8 characters long which means any index beyond 7 is in fact undefined.
If you have no direct access to the $_SESSION superglobal for some odd reason, you need to retrieve the entire slots_id array via the helper, update the index you need in your local copy, then update the session variable's slots_id array with your updated copy.

Undefined offset in array - But I know it's in there

I have an array (or associative array), with keys and values.
Then, when trying to read one of the keys, which IS in the array, I get an "undefined offset" notice.
I have two examples where it happened. One was "exploding" a string like "AAA|BBB|CCC", using | as the separator, then trying to read the resulting array at position 1.
var_dump() correctly shows an array having offsets 0 to 2, with the correct values. But I still get the notice.
Another example is I get an array (from an AJAX call, I json_decode it, etc), then I typed the following code:
foreach (array_keys($myDecodedArray) as $k) {
$value = $myDecodedArray[$k];
someOtherCode();
}
I had that damn notice appear when trying to read $myDecodedArray[$k], although php itself had just told me the key existed !
So, I solved that last case by going
foreach ($myDecodedArray as $k => $value) {
someOtherCode();
}
but still, this is extremely annoying, and makes no sense to me.
Any of you run into that problem before?
Do you have any information about what could cause that?
[EDIT]
Rahul Meshram's suggestion (which I upvoted in the comments) solved my second problem case.
However, the first case still happens (exploding a string into an array, then trying to access that array's values by their numeric keys).
The keys ARE numeric (gettype returns 'integer', var_dump on that key shows an integer too, with the right value), but trying to access $explodedArray[1] still results in that notice being displayed, despite $explodedArray having keys 0, 1, and 2, with associated values.

Are keys inherent to arrays?

It seems that all my questions are so basic that I can't find answers for them anywhere, probably because all the guides assume you have at least some basic knowledge. Anyway, on to my question...
With regard to PHP, are keys inherent to arrays? In other words, if I get data from a form that gives me a set of values in the $_POST array, are there keys assigned to the values by default, or do keys only exist if they are created explicitly? I am assuming there are no keys if I don't create them, but I suspect that there could be numerical keys assigned to each value automatically.
In the most basic sense - "key" is just an instruction for computer how to find required value in the array. So key is like an address of value cell. And you don't find a house in a city without an address - so you will likely don't find value in the array without a key either. Most programming languages supports plain arrays, where key is just an integer - 0,1,2,3,... Consider this array's element layout in memory:
Element index/key: 0 1 2 3 4
Value: A B C D E
And when you ask for a computer - give me array[3] element - it knows that
it needs to look at memory cell array_byte_offset_in_ram + size_in_bytes_of(array_element) * 3
Same instruction expressed in human language will be "find where first array element is stored in memory and jump from it forward in memory by 3x memory amount which is needed to store 1 array element". By doing this algo finds your cell and fetches your value D.
For arrays of arbitrary keys, when key can be any string - is another story. But idea remains the same - from the key computer should deduce How to find required element cell in memory. Usually this done by translating arbitrary string keys into integer hash values. Then sorting these hashes and performing binary search algorithm to find integer-index of required hash value. Last step is to pass index found into another plain array where your real values are stored.
Consider this array:
Element key: 'ABC' 'EFG' 'CDE'
Value: a b c
There are many ways to calculate hashes, but for simplicity consider stupid hash function
hash(string) = sum(ascii_values_of_chars_in_string)
So we have following hash table:
hash('ABC') = ord('A')+ord('B')+ord('C')
hash('EFG') = ord('E')+ord('F')+ord('G')
hash('CDE') = ord('C')+ord('D')+ord('E')
After sorting hashes we generate and save such hash array:
hash[0] = 198
hash[1] = 204
hash[2] = 210
Now we can save array values into another plain array where integer index should be the same as hash array index of saved hash(key) function output =>
value[0] = 'a'
value[1] = 'c'
value[2] = 'b'
Now when you request - give me array['EFG'] value - computer calculates key 'EFG' hash which is 210. Then by employing binary search algo finds 210 value in hash table and deduces that it's index in hash table is 2. So it jumps to value table at index 2 by using above described technique of plain arrays and fetches resulting value of 'b' which will be returned to you.
These are the main principles of array keys. Of course there are much more things under the hood - such as hash collisions and etc. But at this point you don't need more complexities as for now. Simply keep in mind that at most bare-bones of computer architecture - there is only plain numbers and math operating on them - no fancy things like "strings"/"objects" and another cosmos :-)
If you assign an existing array to a new variable, it will be like you copied that array to that variable.
So let's say you have:
$initialArray = ["test1" => "My First Test", "test2" => "My Second Test"];
If you initialize a new variable and say it should be equal to the array you desire:
$aNewArray = $initialArray;
Your new array will be exactly like the one you said for it to copy;
Also, if you change $initialArray after you copied to the $aNewArray, your changes will only affect the variable you change, keeping your $aNewArray with the same data before you changed.
Now, if you just set a few variables into an array without specifying keys to access them, it will automatically link them by numeric index:
$arrayWithoutSpecificKeys = ["one", "two", "three"];
print_r($arrayWithoutSpecificKeys);
This output will be:
array (
0 => "one",
1 => "two",
2 => "three"
);
Never forget array start with index 0;
This means if you assign $_POST to a variable, it will inherit the key => values transmitted.
In your form you will name you inputs like this:
<input type="text" name="surname" .../>
Your $_POST variable will have an array with whatever information you set in your input, and link them as bellow:
["surname" => "<your typed value>"]
Then again, if you copy the $_POST to a variable, that variable will inherit all the content that $_POST contains;
Hope it helped!
An array in PHP is actually an ordered map. A map is a type that
associates values to keys.
PHP Documentation
This means that you can only have one index, however you need to be aware that arrays implement an internal pointer, and technically you can iterate the array by sequentially hopping through each array entry. This is what foreach does for you. You can check next documentation for more details.
In case if you don't supply keys when creating an array, then keys will be assigned automatically. Array created by the following line of code will assign index (key) for each of its elements (starting from 0):
$array = array("foo", "bar", "hello", "world");

Push or Merge data into existing Array

When working with existing code, it takes one array and places it into another in the fashion shown below.
I believe the empty brackets are the same thing as simply pushing it and appending it to the first available index.
$g['DATA'][] = $p;
After this is done, I have my own array that I would like to append to this as well. I tried using array_merge() with $g['DATA'][]as a parameter, but this is invalid for obvious reasons.
My only thought is to create a foreach loop counter so I can figure out the actual index it created, however I have to assume there is some cleaner way to do this?
Just simply use the count() of your $g["DATA"] array as index and then you can merge it like this:
$g['DATA'][count($g["DATA"])-1] = array_merge($g['DATA'][count($g["DATA"])-1], $ownArray);
//^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
// -1 Because an array is based index 0 -> means count() - 1 = last key

when selecting random values from arrays, make sure two certain ones do not appear next to each other

I have an array with 18 values in it from which I select random values using $array[rand(0,17)]. I put these randomly selected values next to each other on the page. Within the array are 6 sets of values that I do not want to be put next to each other on the page. Is there any way that I can detect when the pairs are together and select new values because of that
warning: Do you know for sure that you won't get any degenerate cases where there are no possible orderings of the array? For example, if you won't allow the pairs [1,2] or [2,1] and the array you get is [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2], the you're out of luck. There's no way to display the array in the way you want, and a method like I describe below will never terminate.
I would use shuffle($array) and then iterate through the shuffled array one item at a time, to find out whether any value is "incompatible" with the item before it. If so, just reshuffle the array and try again. You can't predict how many tries it will take to get a shuffled array that works, but the amount of time it takes should be negligible.
To detect whether two values are compatible, I'd suggest making an array that contains all incompatible pairs. For example, if you don't want to have the consecutive pairs 1 and 3 or 2 and 5, then your array would be:
$incompatible = array(
array(1,3),
array(2,5) );
Then you'd iterate over your shuffled array with something like:
for ($i=1; i<count($array)-1; i++;) {
$pair = $array[i, i+1]; // this is why the for loop only goes to the next-to-last item
if in_array($pair, $incompatible) {
// you had an incompatible pair in your shuffled array.
// break out of the for loop, re-sort your array, and try again.
}
}
// if you get here, there were no incompatible pairs
// so go ahead and print the shuffled array!
Or use with unset() for remove the keys, or use by Session, for next skip.

Categories