Handling Complex Arrays in PHP - php

I've worked with arrays in the past with PHP, but generally simple associative arrays that are easy to manage and crawl.
I am making an HTTP POST request to an API endpoint that returns a lot of data in JSON format. I'm using json_decode($response, true) to convert the json into an array, and am trying to access components of the array without luck - just serving me a blank page. Alternatively, if I do print_r on the array I just get a jumble of data, so I know at least the API is returning data.
Here's a snippet of the response from the API
{
"data": {
"accounts": [
{
"locations": [
{
"name": "Test Location",
"soundZones": [
{
"name": "Main",
"nowPlaying": {
"startedAt": "2017-09-06T00:38:51.000Z",
"track": {
"name": "Some Song Name 123",
"imageUrl": "https://some-cdn-url.com",
"Uri": "5hXEcqQhEjfZdbIZLO8mf2",
"durationMs": 327000,
"artists": [
{
"name": "SomeName",
"Uri": "5lpH0xAS4fVfLkACg9DAuM"
}
]
}
}
}
]
},
How would I use PHP to access, let's say, the NAME value under the track object? (In this example I'd be trying to return the value "Some Song Name 123")
Here's the code I'm using.. I know I'm way off
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$response = json_decode($response, true);
print_r($response[0]);

That's because you're being returned not just an array, but both an array and an object.
<?php
echo $response[0]->data->accounts[0]['locations'][0]->soundZones[0]->nowPlaying->track->name;

I like sf_admin's answer better, because this kind of messy object really lends itself more to being an object, but using json_decode($response, true) then I think you should be able to access it like this:
echo $response[0]['data']['accounts'][0]['locations'][0]['soundZones'][0][0]['nowPlaying']['track']['name'];

Try this.
//$response = json_decode($response, true);
$response = json_decode($response);
// loop
if (isset($response->data->accounts)) {
foreach ($response->data->accounts as $account) {
foreach ($account->locations as $location) {
foreach ($location->soundZones as $soundZone) {
print_r($soundZone->nowPlaying->track->name);
}
}
}
}
// first
if (isset($response->data->accounts[0]->locations[0]->soundZones[0]->nowPlaying->track->name)) {
print_r($response->data->accounts[0]->locations[0]->soundZones[0]->nowPlaying->track->name);
}
Some Song Name 123

Related

Extract data from JSON with PHP?

i want to take data of username(david) from this Json , I saw the similar question i try more than 100 times but i can not , I need exact answer if it's possible.
thanks in advance
{
"related_assets": [],
"orders": [],
"auctions": [],
"supports_wyvern": true,
"top_ownerships": [
{
"owner": {
"user": {
"username": "david"
},
"",
"address": "",
"config": ""
},
"quantity": "1"
}
],
"ownership": null,
"highest_buyer_commitment": null
}
and i coded as below :
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
//the second parameter turns the objects into an array
$decodedData = json_encode($response, true);
$owner = $decodedData['top_ownerships'][0]['owner'];
$username = $owner['user']['username'];
echo $username;
}
the output is "
please help thanks
your code is completely current! and it works like charm!
but you made a very ambiguous mistake in your JSON code
you're using this ” instead of " (double quotes) there "david” <----
they exactly look the same!
and also you missed {} in the beginning and end of your JSON code
checkout your json code here it's the best tool for this
<?php
$code = '{
"top_ownerships": [{
"owner": {
"user": {
"username": "david"
},
"profile_img_url": "",
"address": "",
"config": ""
},
"quantity": "1"
}]
}';
$decodedData = json_decode($code, true);
$owner = $decodedData['top_ownerships'][0]['owner'];
$username = $owner['user']['username'];
echo $username;
?>
To start with, it's important you understand how to access json fields and key php;
Assuming the above values are stored in a file known as data.json, we can extract the values like this:
$data = file_get_contents('data.json');
//the second parameter turns the objects into an array
$decodedData = json_decode($data, true);
$owner = $decodedData['top_ownerships'][0]['owner'];
$username = $owner['user']['username'];
//echo $username
The above would work if your json file or data is properly encoded.
first you have to store your JSON into a variable, lets call it $json.
$jsonArray = json_decode($json,true);
And set your key name, the key you want from your JSON.
$key = "owner";
$owner= $jsonArray[$key];
You also can read like an object:
$owner= $jsonObj->$key;
Try
$object = json_decode('{"owner": {"user": {"username": "david”},"profile_img_url": "","address": "","config": ""},"quantity": "1"}')
echo $object->owner->user->username
This will make the JSON an object that you can access by using the -> accessor

Trouble With API Curl Response(php)

I am having trouble with the response from Companies House API. I am making the following curl request from a php page:
$request_url_1 ='https://api.companieshouse.gov.uk/company/' ;
$company_number = 11495745;
$request_url_2 = '/officers';
$request_url = $request_url_1 . $company_number . $request_url_2;
$ch = curl_init($request_url);
$headers = array(
'Content-Type: application/json',
'Authorization: Basic '. base64_encode("$chkey:")
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$content = curl_exec($ch);
curl_close( $ch );
$contents = json_decode($content,true);
The following is the response that is 'pasted' on the php page after sending the curl request, and I cannot seem to get at the contents/value of the $contents variable that should contain the curl response.
{
"active_count":1,
"items_per_page":35,
"kind":"officer-list",
"etag":"6cc48213158205c9fa85492a4c2ef0a98b56b2f1",
"resigned_count":2,
"items":[
{
"date_of_birth":{
"year":1963,
"month":2
},
"appointed_on":"2019-08-01",
"nationality":"British",
"address":{
"address_line_1":"Moorside Crescent",
"country":"United Kingdom",
"address_line_2":"Sinfin",
"postal_code":"DE24 9PH",
"locality":"Derby",
"premises":"75"
},
"occupation":"Company Director",
"links":{
"officer":{
"appointments":"/officers/IryiaaBZodlGNaOP0Rf3Pb2GnO8/appointments"
}
},
"name":"MILLER, Eira",
"country_of_residence":"England",
"officer_role":"director"
},
{
"date_of_birth":{
"month":3,
"year":1987
},
"nationality":"English",
"occupation":"Company Director",
"address":{
"locality":"Derby",
"address_line_1":"Moorside Crescent",
"premises":"75",
"country":"United Kingdom",
"postal_code":"DE24 9PH",
"address_line_2":"Sinfin"
},
"appointed_on":"2018-12-10",
"resigned_on":"2019-07-31",
"name":"KING, Kimberley Rachel",
"links":{
"officer":{
"appointments":"/officers/av7G3-iF_9-FXhRH2xm-IxejeGQ/appointments"
}
},
"country_of_residence":"United Kingdom",
"officer_role":"director"
},
{
"address":{
"postal_code":"DE24 9PH",
"locality":"Derby",
"country":"United Kingdom",
"premises":"75",
"address_line_2":"Sinfin",
"address_line_1":"Moorside Crescent"
},
"occupation":"Managing Director",
"nationality":"British",
"appointed_on":"2018-08-01",
"resigned_on":"2018-12-10",
"officer_role":"director",
"country_of_residence":"United Kingdom",
"links":{
"officer":{
"appointments":"/officers/X9nlVD6qIIENMjaH946__4CB3QE/appointments"
}
},
"name":"MARTIN, Katey",
"date_of_birth":{
"month":6,
"year":1968
}
}
],
"links":{
"self":"/company/11495745/officers"
},
"inactive_count":0,
"start_index":0,
"total_results":3
}
I have tried returning result as non-associative array and access it through normal array but no joy there either.
FluffyKitten kindly supplied the following code to perform the extraction of the name field:
$item = $contents["items"];
foreach($item as $items){
echo $items["name"];
}
However, this couldn't access the required data. A print_r of $contents results in '1' and a var_dump (1)
There are a couple of problem with your code:
You are mixing up code for accessing arrays and objects
You are looping when there is no need for loops
You are using json_decode($content,true), and by passing in that true parameter, you are converting the result into associative arrays, but then you try to access items as the property of an object.
Because you have converted the contents to an associative array, you can easily access the information you want using the correct keys, e.g.:
$item = $contents["items"];
foreach($item as $items){
echo "<p>".$items["name"];
}
Reference PHP json_decode Documentation
UPDATE:
Your question has changed totally - it was about how to loop through the variable with the results, but now it seems that the problem is saving the results as a variable in the first place.
You need to set the CURLOPT_RETURNTRANSFER option to true so that the result is not output directly (I assume this is what you mean by the result being "pasted" into the PHP page).
Add this to your CURL code, and if the rest of your code is correct, the result should be saved in the $content variable so you can use it to loop through using the code above:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

Error getting a json response from http request

I am trying to get the response from an http request from the Hunter API.
The url is something like this :
https://api.hunter.io/v2/email-finder?domain=mydomain&api_key=myapikey&first_name=myfirstname&last_name=myname
And the response is something like this :
{
"data": {
"email": "emailfound#domain.tld",
"score": 68,
"domain": "domain.tld",
"sources": [
{
"domain": "domain.tld",
"uri": "http://somedomain.tld/",
"extracted_on": "2017-04-04"
}
]
},
"meta": {
"params": {
"first_name": "myfirstname",
"last_name": "mylastname",
"full_name": null,
"domain": "domain.tld",
"company": null
}
}
}
Here is what I am doing in my controller :
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
// return response
$json = new JsonResponse();
$datas = $json->setData($response);
return json_encode($datas);
And here is what json_encode($datas) returns :
{"headers":{}}
I precise that I am working with Symfony3 and testing on my OVH serveur (Performance offer).
Any idea where does come from this response ? and why I am not getting the real response ? Thanks !
As per my comment,
Instead of using CURL (Which is a much harder system to deal with IMO), you should use file_get_contents() like so:
$json = file_get_contents($url);
$obj = json_decode($json,true);
Try this:
$json = file_get_contents('https://api.hunter.io/v2/email-finder?domain=mydomain&api_key=myapikey&first_name=myfirstname&last_name=myname');
$data = json_encode($json,true)
var_dump($data);

Pulling data from weird JSON array response

I am working with an API and the response comes back weird. I need to grab the ID field from the response below.
{
"message_campaigns": [
{
"embedded_errors": [],
"id": "2729",
"is_legacy_message": false,
"is_setup_complete": false,
"message_campaign_type_id": 1,
"name": "Message Campaign 1",
"organization_id": 123
}
]
}
Below is my attempt:
$result = curl_exec($ch);
curl_close($ch); // Seems like good practice
$responseData = json_decode($result, TRUE);
print_r($responseData);
I have tried several methods and cannot get it to work
$responseData[0]['id'];
$responseData->id;
I can't figure out how to get the id to display.
Assuming your curl_exec actually returns a response because you've set curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
If I look at your json response you need:
$responseData['message_campaigns'][0]['id'];
It's because the result is an array, as you pass the second parameter as true to json_decode:
When TRUE, returned objects will be converted into associative arrays.
In JSON, {} stands for objects, and [] stands for array. You've converted all objects to associative arrays, so this'll work:
$responseData['message_campaigns'][0]['id']
You have the second parameter of json_decode set to true, so an array (not an object) will be returned.
You'll also need to access message_campaigns as the first item in the array.
$responseData['message_campaigns'][0]['id'];
This can be tested:
$result = <<< EOT
{
"message_campaigns": [
{
"embedded_errors": [],
"id": "2729",
"is_legacy_message": false,
"is_setup_complete": false,
"message_campaign_type_id": 1,
"name": "Message Campaign 1",
"organization_id": 123
}
]
}
EOT;
$responseData = json_decode($result, TRUE);
echo $responseData['message_campaigns'][0]['id'];
// 2729

Unable to parse JSON web service response with json_decode()

I'm struggling with parsing a web service response JSON in cases where the service returns an error.
Example JSON - success flow:
{
"Response": [{
"iconPath" : "/img/theme/destiny/icons/icon_psn.png",
"membershipType": 2,
"membershipId": "4611686018429261138",
"displayName": "Spuff_Monkey"
}],
"ErrorCode": 1,
"ThrottleSeconds": 0,
"ErrorStatus": "Success",
"Message": "Ok",
"MessageData":{}
}
Example JSON - error flow:
{
"ErrorCode": 7,
"ThrottleSeconds": 0,
"ErrorStatus": "ParameterParseFailure",
"Message": "Unable to parse your parameters. Please correct them, and try again.",
"MessageData": {}
}
Now my PHP:
function hitWebservice($endpoint) {
$curl = curl_init($endpoint);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
$json_response = curl_exec($curl);
if(curl_exec($curl) === false) {
echo "Curl error: " . curl_error($curl);
}
curl_close($curl);
$array_response = json_decode($json_response, true);
$function_response = array();
if (!isset($array_response['Response'])) {
$function_response = $array_response;
} else {
$function_response = $array_response['Response'];
}
return $function_response;
}
What I'm trying to achieve is when the JSON includes the "Response" block I put that in a new array and return only that detail from the function, where "Response" isn't present I want to return the full JSON as an array.
However at present, where there is no "Response" I get an empty array.
There's something wrong with my logic and I can't get past it in my tiny mind, so it's time to reach out for help!
Judging from the fact that Response is an array of objects in the JSON, I suspect that the error-flow response may also contain a Response-field, but with an empty array as value ([]). That would explain your current result.
Therefore, do not check for the existence of Response. It may just be an empty array. Instead, check for the ErrorCode, ErrorStatus or ErrorMessage (whichever you think is most suitable). For example:
if ($array_response['ErrorStatus'] != "Success") {
$function_response = $array_response;
} else {
if (!isset($array_response['Response'])) {
$function_response = null;
} else {
$function_response = $array_response['Response'];
}
}
In the Success-case, you want to check for existence of Response, so that if it does not exist (but it is expected), you can raise some error).
Another possible solution is to count the number of responses:
if (!isset($array_response['Response'])) {
$function_response = $array_response;
} else {
if (count($array_response['Response']) > 0) {
$function_response = $array_response['Response'];
} else {
$function_response = $array_response;
}
}
If you notice, both a good and a bad response contain an ErrorCode
You would be better designing your code to work from this field rather than test a field that may or may not exist.
So try this instead :-
$array_response = json_decode($json_response, true);
switch ( $array_response['ErrorCode'] ) {
case 1 :
do_errorCode_1_processing($array_response)
break;
case 2 :
do_errorCode_2_processing($array_response)
break;
// etc etc
}
isset () is not the right function for checking if the key in an array is present or not.
Use array_key_exists () instead.
http://php.net/manual/en/function.array-key-exists.php
so your code should look like this:
$array_response = json_decode($json_response, true);
$function_response = array();
if (array_key_exists('Response', $array_response)) {
$function_response = $array_response['Response'];
} else {
$function_response = $array_response;
}
return $function_response;
The above should do the trick.

Categories