Loop through JSON arrays using PHP [duplicate] - php

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 4 years ago.
I'm trying to loop through an array of moves for a Pokemon website. I'm using the API PokeApi (https://pokeapi.co/).
My question is how can I access the moves in these arrays using plain PHP.
I've tried using this just to call 1 move. But I don't know how to access data that's in arrays. Like "move->version-group-details".
$base = "https://pokeapi.co/api/v2/pokemon/";
$id = 1;
$data = file_get_contents($base.$id."/");
$pokemon = json_decode($data);
echo $pokemon->moves[0];
Thanks in advance :)

So you have two methods here you can do so when I run
$base = "https://pokeapi.co/api/v2/pokemon/";
$id = 1;
$data = file_get_contents($base.$id."/");
$pokemon = json_decode($data);
print_r($pokemon->moves[0]);
I get the result:
stdClass Object
(
[move] => stdClass Object
(
[name] => razor-wind
[url] => https://pokeapi.co/api/v2/move/13/
)
[version_group_details] => Array
(
[0] => stdClass Object
(
[level_learned_at] => 0
[move_learn_method] => stdClass Object
(
[name] => egg
[url] => https://pokeapi.co/api/v2/move-learn-method/2/
)
[version_group] => stdClass Object
(
[name] => crystal
[url] => https://pokeapi.co/api/v2/version-group/4/
)
)
[1] => stdClass Object
(
[level_learned_at] => 0
[move_learn_method] => stdClass Object
(
[name] => egg
[url] => https://pokeapi.co/api/v2/move-learn-method/2/
)
[version_group] => stdClass Object
(
[name] => gold-silver
[url] => https://pokeapi.co/api/v2/version-group/3/
)
)
)
)
If you want to access a moves name you will have to run $pokemon->moves[0]->move->name since we are getting an object returned. If you want to get the name inside the move_learn_method of version_group_details you will have to run
$pokemon->moves[0]->version_group_details[0]-> move_learn_method->name
Alternatively, if you want to return all arrays instead of objects just run this
$base = "https://pokeapi.co/api/v2/pokemon/";
$id = 1;
$data = file_get_contents($base.$id."/");
$pokemon = json_decode($data, true);
print_r($pokemon['moves'][0]);
This will now return
Array
(
[move] => Array
(
[name] => razor-wind
[url] => https://pokeapi.co/api/v2/move/13/
)
[version_group_details] => Array
(
[0] => Array
(
[level_learned_at] => 0
[move_learn_method] => Array
(
[name] => egg
[url] => https://pokeapi.co/api/v2/move-learn-method/2/
)
[version_group] => Array
(
[name] => crystal
[url] => https://pokeapi.co/api/v2/version-group/4/
)
)
[1] => Array
(
[level_learned_at] => 0
[move_learn_method] => Array
(
[name] => egg
[url] => https://pokeapi.co/api/v2/move-learn-method/2/
)
[version_group] => Array
(
[name] => gold-silver
[url] => https://pokeapi.co/api/v2/version-group/3/
)
)
)
)
So instead of having to use the object accessor -> you can access the data by using array notation so instead of
$pokemon->moves[0]->version_group_details[0]-> move_learn_method->name
you can now use:
$pokemon['moves']['version_group_details'][0]['move_learn_method']['name']
Hope that helped.

Related

How to get values from an array, inside another array, with stdClass Objects?

I'm trying to get the values from [iso_3166_1] and [title] in an array, which is inside another array.
I have searched and tried several solutions and tips, but none of them works, and now I'm stuck.
The content is fetched like this
$content = json_decode($jsonFile);
Then I have the following content
stdClass Object (
[id] => 508947 [titles] => Array (
[0] => stdClass Object ( [iso_3166_1] => FR [title] => Devenir rouge [type] => )
[1] => stdClass Object ( [iso_3166_1] => MX [title] => Red [type] => )
[2] => stdClass Object ( [iso_3166_1] => LV [title] => Es sarkstu [type] => )
[3] => stdClass Object ( [iso_3166_1] => NO [title] => Rød [type] => )
[4] => stdClass Object ( [iso_3166_1] => SE [title] => Röd [type] => )
[5] => stdClass Object ( [iso_3166_1] => PE [title] => Red [type] => )
)
)
I have tried to make a foreach loop like this for instance, but that only gives me Warning: Invalid argument supplied for foreach():
foreach($content as $row) {
foreach($row['titles'] as $country) {
echo $country['iso_3166_1']['title'];
}
}
I have also tried tho following, to try get rid of the stdClass Objects in the array, which does not seem to work either:
$content = json_decode(json_encode($content), true);
$content = (array)$content;
this should work for you to compare & understand why your code fails.
$titles = $content->titles;
foreach ($titles as $country_instance) {
echo $country_instance->iso_3166_1;
echo '-';
echo $country_instance->title;
echo '<br>';
}
If I understand the question right, json_decode associative mode should return arrays of arrays from your JSON.
$array = json_decode($json, true);
You can also try using flag JSON_OBJECT_AS_ARRAY but from what I've read it only does something when null is supplied as the second argument.

PHP efficiently accessing values in a JSON array on different levels

Working on a personal project that will pull results from an API with full details of each pokemon.
So far I got the contents of the URL and returned the results into a JSON array format.
At the moment I am stuck on trying to retrieve results for[stats] inside from the array in an efficient manner.
private function getGenOnePokemon()
{
// the url of the api
$url = $this->baseUrl;
//get the contents of $url var and decode it into a json array
$json = file_get_contents($url , true);
$pokemon = json_decode($json, true, JSON_UNESCAPED_UNICODE);
// array output of pokemon
echo '<pre> ';
print_r($pokemon);
echo'</pre>';
//echo out value as speed
foreach($pokemon['results'][0] as $happy)
{
echo $happy['name'] . '<br />';
}
// echo base_stat value for speed with value of 90
echo $pokemon['stats'][0]['base_stat'];
}
However I do not seem to get anywhere much printing values/keys as I need to add something else to have full access to the values?
Would prefer not to directly access results, like I am doing with base_stat as plan on using this logic to pass into HTML View layer later.
Example of print_r dump (not full dump as really long) Full example: https://pokeapi.co/api/v2/pokemon/pikachu
Array
(
[forms] => Array
(
[0] => Array
(
[url] => https://pokeapi.co/api/v2/pokemon-form/25/
[name] => pikachu
)
)
[abilities] => Array
(
[0] => Array
(
[slot] => 3
[is_hidden] => 1
[ability] => Array
(
[url] => https://pokeapi.co/api/v2/ability/31/
[name] => lightning-rod
)
)
[1] => Array
(
[slot] => 1
[is_hidden] =>
[ability] => Array
(
[url] => https://pokeapi.co/api/v2/ability/9/
[name] => static
)
)
)
[stats] => Array
(
[0] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/6/
[name] => speed
)
[effort] => 2
[base_stat] => 90
)
[1] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/5/
[name] => special-defense
)
[effort] => 0
[base_stat] => 50
)
[2] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/4/
[name] => special-attack
)
[effort] => 0
[base_stat] => 50
)
[3] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/3/
[name] => defense
)
[effort] => 0
[base_stat] => 40
)
[4] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/2/
[name] => attack
)
[effort] => 0
[base_stat] => 55
)
[5] => Array
(
[stat] => Array
(
[url] => https://pokeapi.co/api/v2/stat/1/
[name] => hp
)
[effort] => 0
[base_stat] => 35
)
)
Any advice on how to access the data using foreach or other tips greatly appreciated. Thank you!
PHP has a specific function designed to target columnar data from arrays. It is called array_column()
If you want to isolate all of the name elements inside the forms subarray, use this:
$names=array_column($pokemon['forms'],'name');
If you want to isolate all of the base_stat elements inside of the stats subarray, use this:
$base_stats=array_column($pokemon['stats'],'base_stat');
Now you will have $names and $base_stats which are single-dimensional arrays by which you can perform additional processes or return from the function. Clean, intuitive, and simple.
Your $pokemon array doesn't contain a results field. There's only an forms field. So you should iterate over forms to print the names of the forms.
foreach($pokemon['forms'] as $happy) {
echo $happy['name'] . '<br />';
}
You could do the same thing with the stats
foreach($pokemon['stats'] as $stat) {
$base_stat = $stat['base_stat'];
// ...
}

Issue accessing objects within objects in a file with XML format

I have a XML format file which has objects inside objects. This is how I get values of first object, which works fine for me:
$soapclient = new SoapClient('http://anywb/book.asmx?WSDL');
$params = array('ISBN' => "1111");
$response = $soapclient->GetBookByISBN($params);
//This will give me the value "Success"
$result = $response->GetBookByISBNResult->ResponseText;
Now my question is how to access the object which is inside object. For example, how to get "BookID" which is 4 and how to get value of "Type" which is 1?
Any suggestion would be appreciated. Here is the object:
stdClass Object
(
[GetBookByISBN] => stdClass Object
(
[ResponseText] => Success
[SearchResult] => stdClass Object
(
[Search] => Array
(
[0] => stdClass Object
(
[Date] => 2015-10-20
[BookID] => 4
[Discription] => stdClass Object
(
[Type] => 1
)
[Probability] => stdClass Object
(
[Kids] =>
[Adult] => 00
)
)
[1] => stdClass Object
(
[Date] => 2016-11-15
[BookID] => 5
[Discription] => stdClass Object
(
[Type] => 2
)
[Probability] => stdClass Object
(
[Kids] =>
[Adult] => 00
)
)
))))
You do it like this:
$response->GetBookByISBN->SearchResult->Search[0]->BookID;
$response->GetBookByISBN->SearchResult->Search[0]->Discription->Type;
If you would like to have an array containing all book ids you would have something like this:
$BookIDs = array();
foreach($response->GetBookByISBN->SearchResult->Search as $key => $value) {
$BookIDs[$key] = $value->BookID;
}
Or if you would like to be able to modify the values in $response using the $BookIDs (as an example) iot would look like this:
$BookIDs = array();
foreach($response->GetBookByISBN->SearchResult->Search as $key => $value) {
$BookIDs[$key] = &$value->BookID;
}

HubSpot api json decode

I am trying to parse some data out of the Hubspot API response. The response looks like this json_decoded:
stdClass Object(
[addedAt] => 1411052909604
[vid] => 24
[canonical-vid] => 24
[merged-vids] => Array
(
)
[portal-id] => XXXXX
[is-contact] => 1
[profile-token] => AO_T-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[profile-url] => https://app.hubspot.com/contacts/XXXXX/lists/public/contact/_AO_T-XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[properties] => stdClass Object
(
[lastname] => stdClass Object
(
[value] => testtt
)
[firstname] => stdClass Object
(
[value] => test
)
[lastmodifieddate] => stdClass Object
(
[value] => 1411052906670
)
)
[form-submissions] => Array
(
[0] => stdClass Object
(
[conversion-id] => 85d24dd2-9ee9-4d47-b8f3-3035acbd8f3b
[timestamp] => 1411052834097
[form-id] => fb16efd9-23cc-4511-889c-204fc8b41dba
[portal-id] => 401824
[page-url] => http://wbl-1.hs-sites.com/test
[canonical-url] => http://wbl-1.hs-sites.com/test
[content-type] => landing-page
[page-title] => test
[page-id] => 1570433242
[title] => Default Form (Sample)
[first-visit-url] => http://wbl-1.hs-sites.com/test
[first-visit-timestamp] => 1411052722970
[meta-data] => Array
(
)
)
)
[list-memberships] => Array
(
)
[identity-profiles] => Array
(
[0] => stdClass Object
(
[vid] => 24
[identities] => Array
(
[0] => stdClass Object
(
[type] => EMAIL
[value] => test#user.com
[timestamp] => 1411052834097
)
[1] => stdClass Object
(
[type] => LEAD_GUID
[value] => 0b6acf21-6cee-4c7b-b664-e65c11ee2d8e
[timestamp] => 1411052834201
)
)
)
)
[merge-audits] => Array
(
)
)
I'm looking specifically to try to dig out an email inside the indentities-profile area.
I've tried to do the following:
echo $results->contacts[0]->identity-profiles;
But it just gives me a value of 0
Then I try to go further into the array by doing:
echo $results->contacts[0]->identity-profiles[0];
But at that point - I get a parse error:
Parse error: syntax error, unexpected '['
What am I doing wrong? And how can I dig all the way down to
identity-profiles[0]->identities->[0]->value
which should equal: test#user.com
What am I missing?
As mentioned in the comment I would suggest to decode the JSON to an associative array by passing true as second parameter to json_decode. Example: json_decode($data, true) Than you could access your identity profiles by:
$results['contacts'][0]['identitiy-profiles']
If you still want to get the results as an object you have to access the properties the following way because they contain a -:
$results->contacts[0]->{'identity-profiles'}

How can I merge or search an object?

Here's my issue:
I have an object filled with arrays that look like this.
[376339] => Array
(
[0] => 1f422730-f54b-4e4d-9289-10258ce74446
[1] => 60dc4646-06ce-44d0-abe9-ee371847f4df
)
I need to search another object to find objects with the matching IDs, like below. Is there a way of doing this without a foreach? There are SEVERAL and I would like to not have to loop over the entire object every time.
stdClass Object
(
[id] => 1f422730-f54b-4e4d-9289-10258ce74446
[percentage] => 32
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 59826
[destination_id] => 59826
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxx
)
)
)
stdClass Object
(
[id] => 60dc4646-06ce-44d0-abe9-ee371847f4df
[percentage] => 68
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 60046
[destination_id] => 60046
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxxx
)
)
)
I need it to end up looking like this.
[376339] => Array
(
[0] => Array
(
[id] => 1f422730-f54b-4e4d-9289-10258ce74446
[percentage] => 32
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 59826
[destination_id] => 59826
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxx
)
)
)
[1] => Array
(
[id] => 60dc4646-06ce-44d0-abe9-ee371847f4df
[percentage] => 68
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 60046
[destination_id] => 60046
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxxx
)
)
)
)
I'm not sure if this makes any sense, that's why I had my two inital outputs I need to have merged into one somehow. This is all coming from one huge json object and I'm just using json_decode($jsonStuff) to decode it.
Would this be easier if I added true in the decode function? If I could just search for it like I could in python, that would be neat. But as it is, I'm at a loss as to how to get the output I need.
Note: Input json CANNOT be changed, I have no affiliation with the people that created it.
First loop over your input array and create an array with the key as the id
$input = json_decode($json_input);
$output = array();
foreach($input as $obj){
$output[$obj->id] = $obj;
}
then you can build your other array by searching the id on the array key
$massive_search_array = array(376339 => array
(
0 => 1f422730-f54b-4e4d-9289-10258ce74446,
1 => 60dc4646-06ce-44d0-abe9-ee371847f4df
)
);
$final_output = array();
foreach($massive_search_array as $index => $searches){
foreach($searches as $search){
if(isset($output[$search])){
$final_output[$index][] = $output[$search];
}
}
}

Categories