Get Key from php Array - php

I am using simplepie to get some feeds, I have set the key in the array which I am having trouble accessing. Here's my code:
$feed->set_feed_url(array(
'Title One'=>'http://example.com/rss/index.xml',
'Title Two'=>'http://feeds.example.com/rss/example',
'Title Three'=>'http://feeds.example.com/ex/blog'
));
When I loop over and try to access it I'm getting errors, here's how I am trying to access it.
foreach ($feed->get_items() as $item):
echo $item[0];
Fatal error: Cannot use object of type SimplePie_Item as array
How can I access those I tried also:
echo $item->[0];
without luck.

When you loop over an array (often used with associative arrays) using foreach, there is an additional construct to be able to get the key. It looks like this:
foreach ($feed->get_items() as $key => $item) {
echo($key);
}
So an array with a structure like:
$myArray = [
'a' => 1,
'b' => 2,
];
When iterated with foreach in that syntax, will put "a" or "b" in the $key variable depending on which iteration it is, and $item will contain either "1" or "2".
In your case, $item is the object instance and then you are trying to access it like it is an array. If you need to know the key, use that other foreach syntax.
To get the title of the SimplePie_Item object, you can call get_title():
foreach ($feed->get_items() as $index => $item) {
echo($item->get_title());
}

Related

Parsing changing JSON from API - what design pattern to use - PHP

I am getting article/articles from an API. The JSON object varies, some articles have properties that some other do not have.
I need to iterate through the items and manipulate the properties, if they are set.
What is the best way to tackle this?
Actually for now I do something that I find very ugly...
foreach ($items as $key => $item) {
if(isset($item->title)){
$parsed[$key]['title'] = $this->formatTitle($item->title);
}
if(isset($item->salutation)){$parsed[$key]['salutation'] = $item->salutation;}
if(isset($item->eventDate) && isset($item->enventEndDate)){
$parsed[$key]['eventDates'] = $this->ersDate($item->eventDate, $item->eventEndDate);
$parsed[$key]['startDateTimestamp'] = $this->toTimestamp($item->eventDate);
} elseif(isset($item->eventDate) && !isset($item->enventEndDate)){
$parsed[$key]['eventDates'] = $this->ersDate($item->eventDate);
$parsed[$key]['startDateTimestamp'] = $this->toTimestamp($item->eventDate);
}
//... code continues ...
Since your source has unpredictable shape, I don't think there is any way around parsing the data.
You can abstract the ugliness in a separate function, so that your main script just does:
$parsed = parseAPI($items);
If you use $items = json_decode($apiResponse,true), you get an array instead of an object. You can then use the + operators on arrays along with a default array to cast all API responses to the same shape.
$defaultItem = [
'salutation' => null,
'eventDate' => null,
'eventEndDate' => null,
...
];
Now when you get items from the API, you can do:
$items = json_decode($apiResponse,true);
foreach($items as &$item) $item += $defaultItem;
Now each member of $items has all the keys you expect. If any key was missing, $defaultItem's matching key and value was inserted.

PHP paradoxical (weird) behavior. Sending array to function by reference

Could someone explain me, why this code works properly without crashing initial array structure?
function setArrayValueByPath($path, $value, &$array)
{
foreach ($path as $p) {
$array = &$array[$p];
}
$array = $value;
return true;
}
$array = [
'a' => 'v1',
'b' => 'v2',
];
setArrayValueByPath(['hello', 'world'], '!!!', $array);
echo '<pre>';
print_r($array);
echo '</pre>';
When I run the code, I see:
Array
(
[a] => v1
[b] => v2
[hello] => Array
(
[world] => !!!
)
)
Due to the line in function:
$array = $value;
it should replace $array value, but it does not happen.
My function is based on code snippets are given here: Using a string path to set nested array data
Thank you.
Let's examine this one step at a time.
The parameter $array is a local variable within the function which contains a reference to some external array being passed in.
foreach ($path as $p) {
This iterates over ['hello', 'world']
$array = &$array[$p];
Take the original array, and "index" it with $p (i.e. [hello]). This does not currently exist so it is added to the original array. Then take a reference to that new member and save it in the local variable $array. I.e. you just created a new member of the original array, and the local variable $array no longer points to the original external array.
On the second iteration, take the variable currently pointed to by $array (see just above) and index it with $p (world). This does not exist, so create it.
}
At this point $array points to the member {original array}[hello][world]. I use the syntax {original array} here because you no longer have a reference to it, only a reference to an array two levels nested within it.
$array = $value;
This sets the value of that member to !!!, giving exactly the data structure you see.

PHP: reflection, "non well formed numeric value encountered" setting array index

I haven't been able to find anything specific to this issue. In my class I need to take an associative array and put it's values in class variables. Any sub-arrays need to be converted to objects. The conversion to objects is happening in the following code:
foreach ($value as $key2 => $value2) {
$object = new $object_str($value2);
$this->$key[$object->getId()] = $object;
}
$value comes from an outer foreach loop.
$object_str contains the name of the object that has to be created,
like this: MartKuper\OnePageCRM\Contacts\ContactsUrl
The input array could look like this:
[
'url' => [
'type' => 'website',
'value' => 'google.com'
]
]
It should create a ContactsUrl object and add it to the $url class variable (which also is an array) based on the class' internal random id (uniqid()). Because I don't know how many 'url' entries the input array will have, this all needs to happen dynamically. Hence the
$this->$key[$object->getId()]
The error occurs on the index of the $key (url) array. It seems that it doesn't like to take a string as an index. I've tried putting hardcoded strings in
$this->$key['test]
that doesn't work either. When I put an integer in
$this->$key[1]
it does work. Converting the string to an integer is not an option. It will break a parser class that is used by many other classes.
I've solved the issue by doing the following:
$this->{$key}[$object->getId()] = $object;
What was happening was that it tried to take the index of the $key variable itself ($key[$object->getId()]) but since $key isn't an array, it failed. It needed to take the index of the class variable that $key represents instead.

How do a foreach on an object with integer keys?

I'm loading a json file where there's an object data, which has properties that are only integers.
They begin with 1000 then increment until 9999. Everything is ok. The problem comes with the properties 10000 and higher. When I load the file using json_decode(file_get_contents('myjsonfile')), if I try to do a foreach loop I have all the properties that begin with 1000 first, so this includes all the properties 10000 then I have other ones (2000, 3000, and so on).
The actual problem is that I need to keep the keys (because the properties are objects that sometimes contain link to keys of the "base" data object).
How can you make a working foreach loop with keys ordered asc?
I did this using a temporary table to sort key with SORT_NATURAL then foreach on it:
$tmp=array();
foreach ($obj as $key=>$item) {
$tmp[$key]=$item;
}
$tmp=(array_keys($tmp));
sort($tmp, SORT_NATURAL);
foreach ($tmp as $key) {
$item=$obj->$key;
/* ... my other code, with a good iteration ... */
}
Since JSON array keys are strings, that's why you get array sorted automatically.
Use ksort function first:
$array = (array) json_decode(json_encode(array("3000" => "Third", "10000" => "Fourth", "2000" => 'Second', "1000" => 'First')));
ksort($array, SORT_NUMERIC);
foreach ($array as $k => $v) {
var_dump($k, $v); echo "<br/>";
}

PHP - How to find the Auto Increment Array id to unset

I am using a form to create several arrays in a Session. Each time the form is submitted a new $_SESSION['item'][] is made containing each new array. The code for this:
$newitem = array (
'id' => $row_getshoppingcart['id'] ,
'icon' => $row_getimages['icon'],
'title' => $row_getimages['title'],
'medium' => $row_getshoppingcart['medium'],
'size' => $row_getshoppingcart['size'],
'price' => $row_getshoppingcart['price'],
'shipping' => $row_getshoppingcart['shipping']);
$_SESSION['item'][] = $newitem;
There could be any number of item arrays based on how many times the user submits the form. Any ideas how can I get the value of the array key that is being put in place of the [] in the session variable? I am trying to create a remove from cart option and cannot figure out how to reference that particular array in the session to unset it.
I am currently displaying the items as such:
<?php foreach ( $_SESSION['item'] AS $item )
echo $item['title'];
echo $item['icon'];
and so on...
Thank you in advance for your time. I really appreciate it.
foreach($_SESSION['item'] as $key => $value) will enable you to seperate the key and value, and ofcourse, to access the value current key has.
To extend this with an example, consider following code:
<?php
$exArray = array("foo"=>"bar", "foo2"=>"bar2);
foreach($exArray as $arrKey => $arrValue):
echo "The key ".$arrKey." has the value of ".$arrValue."<br />\n";
endforeach;
?>
will output:
The key foo has the value of bar.
The key foo2 has the value of bar2.
However, in the same way, if the $arrValue variable is known to hold an array, it will keep it's content. To loop through that second array, you will need to loop it through another foreach statement.
Just specify an index name in your foreach
foreach ($_SESSION['item'] as $idx => $item) {
var_dump($item);
var_dump($_SESSION['item'][$idx]);
}
The var_dumps will be the same.
$var = array_keys($arr);
$count = count($var);
$lastKey = $var[$count - 1];
That work for you?

Categories