Access array by string key x, where x is "123" - php

We have an array of which the keys are Strings, but those strings sometimes just are numbers (e.g. "123"). When trying to access the array by the key "123", we get an Undefined Index notice. When accessing it by just the integer 123, we get the Undefined Offset notice. This tells us we're trying to index it correctly using the "123" string, but it's still not set.
Trying to come up with an example for this SO question this is hard, since PHP converts array keys in our test case to integers automatically, while in our real-world application this does not happen (due to use of a Java Bridge). The test array we're trying now is:
<?php
$array = array("123" => array(108, 8));
var_dump($array);
?>
This returns:
array(1) { [123]=> array(2) { [0]=> int(108) [1]=> int(8) } }
While in our real-world equivalent, it would return:
array(1) { ["123"]=> array(2) { [0]=> int(108) [1]=> int(8) } }
So in the real world the index actually is a String:
<?php
var_dump(array_keys($array));
?>
returns
array(1) { [0]=> string(3) "123" }
So, finally the question is the output of the following code:
<?php
foreach ($array as $key => $value) {
if (!isset($array[$key])) {
print "What is happening here?";
}
}
?>
which gives:
What is happening here?
Based on Yoshi's comment, here's working test code:
<?php
$array = (array)json_decode('{"123":[108,8]}');
foreach ($array as $key => $value) {
if (!isset($array[$key])) {
print "What is happening here?";
} else {
print "Nothing to see here, move along";
}
}
?>

Not very elegant solution too, but also works and do not require recreating array. Also, you can access the element value.
$array = (array)json_decode('{"123":100}');
$array_keys = array_keys($array);
$array = (object)$array;
foreach ($array_keys as $key)
{
if (!isset($array->$key))
{
print "What is happening here?";
}
else {
print "It's OK val is {$array->$key}";
}
}
Note $ before key in $array->$key, it is important.

Look at this code (and line $array[(string)$key])
<?php
$array = array("123" => array(108, 8));
foreach ($array as $key => $value)
{
if (!isset($array[(string)$key]))
{
print "What is happening here?";
}
else print "It's just types";
}
Type of $key was automatically casted to integer, and it's why this key was not found in array.
All information about it you can find in manual: http://php.net/manual/en/language.types.type-juggling.php
This code will works with both cases:
foreach ($array as $key => $value)
{
if (!array_key_exists($key, $array))
{
print "What is happening here?";
}
else print "It's just types";
}

I had the same problem (but with array_intersect_key).
Here is my solution:
$array = array_combine(array_keys($array), $array)

Related

PHP how to loop over nested JSON Object?

1. Extracted from my laravel controller:
..
..
$data = json_decode($response, true);
return $data;
..
..
return view('homepage')->with('homeExclusives', $homeExclusives);
Here is a sample of the returned data, just a short version, since the returned feed is very large, but this will give you an idea of the way it's structured.
array(4) {
["success"]=> bool(true)
["status"]=> int(200)
["bundle"]=> array(2) {
[0]=> array(631) {
["StreetDirPrefix"]=> string(2) "SW"
["DistanceToStreetComments"]=> NULL
}
[1]=> array(631) {
["StreetDirPrefix"]=> string(2) "NE"
["DistanceToStreetComments"]=> NULL
}
}
I need to extract "StreetDirPrefix" value from [0] and [1], but I always get an error. Can someone help?
For the data in your example you might use array_column and specify StreetDirPrefix as the column key.
$res = array_column($array["bundle"], "StreetDirPrefix");
print_r($res);
Php demo
Without knowing what error you are getting my solution would be something like this:
<?php
if (is_array($data) && is_array($data["bundle"]) ) {
foreach ($data["bundle"] as $tmpKey => $tmpVal) {
if (isset($tmpVal["StreetDirPrefix"])) {
echo $tmpKey." => ".$tmpVal["StreetDirPrefix"]."\n";
}
}
}
?>
I always like to validate arrays, so if your $data variable or the $data["bundle"] subsection are not arrays then you will not get anything. Not even an error.
I have a working example here:
https://www.seeque-secure.dk/demo.php?id=PHP+how+to+loop+over+nested+JSON+Object
EDIT:
(if i understand you correct)
When you have validated your array all you have to do is repeat the inner validation like this:
<?php
if (is_array($data) && is_array($data["bundle"]) ) {
foreach ($data["bundle"] as $tmpKey => $tmpVal) {
if (isset($tmpVal["StreetDirPrefix"])) {
echo $tmpKey." => ".$tmpVal["StreetDirPrefix"]."\n";
}
if (isset($tmpVal["UnparsedAddress"])) {
echo $tmpVal["UnparsedAddress"]."\n";
}
if (isset($tmpVal["SalePrice"])) {
echo $tmpVal["SalePrice"]."\n";
}
//...... ect.....
}
}
?>

Unable to iterate on the content of an array

I have an array which contents data that I can see on doing a var_dump() but I am unable to iterate through its content using foreach()
The var_dump() generates the following output
array(4) { [0]=> array(1) { [0]=> string(5) "Admin" } [1]=> array(1) { [0]=> string(4) "rick" } [2]=> array(1) { [0]=> string(6) "techbr" } [3]=> array(1) { [0]=> string(7) "testdom" } }
I want to be able to get the content of this array and store it in another.
Currently I am using the following code
$empList = array();
$empList = emp_list($mysqli);
var_dump($empList);//This generated the above output
foreach ($empList as $value)
{
echo $value."<br>";
}
Output of the echo is this
Array
Array
Array
Array
How do I sort this out?
Thank you for your suggestions I have modified the code this way
$i=0;
$empList = array();
$tempList = array();
$tempList = emp_list($mysqli);
foreach ($tempList as $value)
{
$empList[$i] = $value[0];
$i++;
}
Now the $empList array stores stuff in the correct format
It has an array inside another array so, use two foreach loops
$empList = array();
$empList = emp_list($mysqli);
foreach ($empList as $value)
{
foreach ($value as $temp)
{
echo $temp."<br>";
}
}
As u_mulder says in the comments on your question, your array isn't an array of strings - it's an array of more arrays. var_dump() is designed to deal with complicated nested contents, but echo can't print arrays - that's why it's just telling you that each item in $empList is an array, and not what its contents are.
If you wanted to get the content out of a specific array in $empList you'd need to access it by its index key, with something like:
$first = $empList[0];
foreach ($first as $value) {
echo $value."<br>";
}
Or if you wanted to iterate through them all you could just put two foreach loops one inside the other.

php loop through array

I am trying to get certain values from an array but got stuck. Here is how the array looks:
array(2) {
[0]=>
array(2) {
["attribute_code"]=>
string(12) "manufacturer"
["attribute_value"]=>
string(3) "205"
}
[1]=>
array(2) {
["attribute_code"]=>
string(10) "silhouette"
["attribute_value"]=>
array(1) {
[0]=>
string(3) "169"
}
}
}
So from it I would like to have attribute_values, and insert it into a new array, so in this example I need 205 and 169. But the problem is that attribute_value can be array or string. This is what I have right now but it only gets me the first value - 205.
foreach ($array as $k => $v) {
$vMine[] = $v['attribute_value'];
}
What I am missing here?
Thank you!
If sometimes, attribute_value can be an array, and inside it the values, you can just check inside the loop (Provided this is the max level) using is_array() function. Example:
$vMine = array();
foreach ($array as $k => $v) {
if(is_array($v['attribute_value'])) { // check if its an array
// if yes merge their contents
$vMine = array_merge($vMine, $v['attribute_value']);
} else {
$vMine[] = $v['attribute_value']; // if just a string, then just push it
}
}
I suggest you to use array_map instead of for loop. You can try something like this..
$vMine = array_map(function($v) {
return is_array($v['attribute_value']) ? current($v['attribute_value']) : $v['attribute_value'];
}, $arr);
print '<pre>';
print_r($vMine);
Try the shorthand version:
foreach ($array as $k => $v) {
$vMine[] = is_array($v['attribute_value']) ? current($v['attribute_value']):$v['attribute_value'];
}
or the longer easier to understand version, both is the same:
foreach ($array as $k => $v) {
if(is_array($v['attribute_value'])) {
$vMine[] = current($v['attribute_value']);
} else {
$vMine[] = $v['attribute_value'];
}
}

Changes to array of JSON objects based on other array

I have an array of JSON objects that look like this:
{"id":1,"place":2,"pic_name":"aaa.jpg"}
My PHP file receives a simple array like:
["4","3","1","2","5"]
These numbers correspond to the place value in my JSON object. Now I need to compare the place of each element in the secont array with the value of ID in the JSON object and if the match I have to replace the value of PLACE with the element from the array.
I am having problems doing the comparison. Any guidelines? What I come up with:
foreach($ids as $index=>$id) { //the array
$id = (int) $id;
foreach ($obj as $key=>$value) { //the JSON objects
foreach ($value as $k=>$v){
if ($id != '' && array_search($index, array_keys($ids)) == $value[$k]['id']) {
$value[$k]['place'] = $id;
file_put_contents($file, json_encode($ids));
} else { print "nope";}
} } }
That will be:
$array = [
'{"id":1,"place":2,"pic_name":"aaa.jpg"}',
'{"id":2,"place":5,"pic_name":"aab.jpg"}',
'{"id":3,"place":1,"pic_name":"aba.jpg"}',
'{"id":4,"place":3,"pic_name":"baa.jpg"}',
'{"id":5,"place":4,"pic_name":"abb.jpg"}'
];
$places = ["4","3","1","2","5"];
$array = array_map(function($item)
{
return json_decode($item, 1);
}, $array);
foreach($array as $i=>$jsonData)
{
if(false!==($place=array_search($jsonData['id'], $places)))
{
$array[$i]['place'] = $place+1;
}
}
$array = array_map('json_encode', $array);
//var_dump($array);
-with output like:
array(5) {
[0]=>
string(39) "{"id":1,"place":3,"pic_name":"aaa.jpg"}"
[1]=>
string(39) "{"id":2,"place":4,"pic_name":"aab.jpg"}"
[2]=>
string(39) "{"id":3,"place":2,"pic_name":"aba.jpg"}"
[3]=>
string(39) "{"id":4,"place":1,"pic_name":"baa.jpg"}"
[4]=>
string(39) "{"id":5,"place":5,"pic_name":"abb.jpg"}"
}

PHP array argument by value, gets modified when looping the array items by reference

I have been having issues with an array being modified when passed by value to a function.
I have inspected the code and inside the function the array is looped getting the elements by reference.
I was surprised to see that after the loop the array items are marked as referenced. I don't know what this means, but must be the origin of my problem.
Let me put an example to see the point.
<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);
$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);
function dummy($arg) {
foreach($arg as &$item) {
$item[0] = 3;
}
dummy2($arg);
echo '--3--';var_dump($arg);
}
function dummy2($arg) {
foreach($arg as &$item) {
$item[1]=9;
}
echo '--2--';var_dump($arg);
}
?>
After this code I would expect that in point 3, $arg would have only one element, but it has two, so it has been modified by dummy2 function.
The output is as follows:
--1--array(1) { [0]=> array(1) { [0]=> int(0) } }
--2--array(1) { [0]=> &array(2) { [0]=> int(3) [1]=> int(9) } }
--3--array(1) { [0]=> &array(2) { [0]=> int(3) [1]=> int(9) } }
--4--array(1) { [0]=> array(1) { [0]=> int(0) } }
Why are the arrays marked as &array after being looped by reference?
How can this be avoid?
You need to unset the loop variable that captures by reference:
<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);
$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);
function dummy($arg) {
foreach($arg as &$item) {
$item[0] = 3;
}
unset($item);
dummy2($arg);
echo '--3--';var_dump($arg);
}
function dummy2($arg) {
foreach($arg as &$item) {
$item[1]=9;
}
unset($item);
echo '--2--';var_dump($arg);
}
?>
See in the documentation for foreach, there is a big red warning that says:
Reference of a $value and the last array element remain even after the
foreach loop. It is recommended to destroy it by unset().
Use key => value pairs and return the array in your functions
<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);
$a = array( array(0) );
echo '--1--';var_dump($a);
$a = dummy($a);
echo '--4--';var_dump($a);
function dummy($arg) {
foreach($arg as $key => $value) {
$arg[$key][0] = 3;
}
return dummy2($arg);
}
function dummy2($arg) {
foreach($arg as $key => $value) {
$arg[$key][1]=9;
}
return $arg;
}
?>
http://codepad.org/f30c6FUj

Categories