Remove the {1} from an array of objects - php

I want my $row->responses object to look like so:
"responses": [
{
"id": 1381822,
"user_id": 45313,
"respondent_name": "JP Pullen",
"response_time": 1424127673,
"is_root_response": true,
"response_tree_id": 1377018,
"project_users_id": 74311,
"display_name": "Mobile 2",
"lft": 1,
"rgt": 2,
"response_read": true,
"body": "Sure it really is was great I purchased choclate at my local grocery store.",
"answers": [ ],
"avatar_url": null,
"mtime": null,
"media_list": [ ]
},
Yet my $row->responses object looks like:
"responses": {
"1": {
"id": 1381825,
"user_id": 45167,
"respondent_name": "First Name Last Name",
"response_time": 1424128177,
"is_root_response": true,
"response_tree_id": 1377021,
"project_users_id": 74312,
"display_name": "SimonSays",
"lft": 3,
"rgt": 4,
"response_read": false,
"body": "What's up!",
"answers": [ ],
"avatar_url": "https:\/\/portalvhds5kcv8nfhdz8zn.blob.core.windows.net\/user-45167\/avatar-50x50",
"mtime": 1420206441,
"media_list": [ ]
}
}
How do you get rid of the stupid {1} in the object. I didn't get it until I had to loop through the objects and unset one of them. I am not a PHP expert. Strongly Typed FTW lol.
foreach($row->responses as $elementKey => $element)
^ That is how I looped through the responses object to unset one:
unset($row->responses{$elementKey});

When arrays are encoded using json_encode() PHP will determine whether it should use array syntax (square brackets) or object syntax (curly brackets). In this case, the first array index is 1 instead of 0 so it can't reliably be encoded as a JavaScript array.
To prevent this from happening, you can use array_values() to renumber the array to be 0-based again:
$row->responses = array_values($row->responses);

Related

How can i get Json Nested attribute value using dynamoDB query in PHP

[{
"forms": [{
"id": "52b55960-023e-11e7-9140-f3c1d163524b",
"title": "Default Form",
"update_history": [{
"version": "1",
"updated_at": "2016-12-10 12:12:10"
}, {
"version": "2",
"updated_at": "2017-01-01 05:17:19"
}, {
"version": "3",
"updated_at": "2017-02-07 03:22:39"
}, {
"version": "4",
"updated_at": "2017-03-03 02:28:56"
}, {
"version": "5",
"updated_at": "2017-01-11 07:01:22"
}]
}]
}]
I have above Json stored in Dynamo-DB table. forms object is parent object. I have stored form updated detail version and updated_at in update_history nested object. I want updated_at of version of 2. Please suggest me, what is wrong in below query. I got empty result.
`$response = $client->scan([
'TableName' => 'TableName',
'ProjectionExpression' => 'Json.forms.update_history.updated_at',
'ExpressionAttributeValues' => [
':val1' => ['S' => '52b55960-023e-11e7-9140-f3c1d163524b'],
':val2' => ['S' => '2']
],
'FilterExpression' => 'id = :val1 and Json.forms.update_history.version = :val2',
]);`
Please refer the DocumentPath example in the below link and try to use deference operator.
For a nested attribute, you construct the document path using
dereference operators.
If you don't know the deference operator (i.e. index), you can't filter the data as you have tried.
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html#DocumentPaths
Example:-
Accessing List Elements:-
MyList[0]
AnotherList[12]
ThisList[5][11]
Accessing Map Elements:-
MyMap.nestedField
MyMap.nestedField.deeplyNestedField
You have the combination of both Map and List, you need to FilterExpression accordingly.

Is there a way to check if value in object is set without using foreach?

I have the following JSON object:
{
"screen": 1,
"parameters": {
"title": "Fill in the form:",
"values": [
{
"id": 13,
"type": 2,
"name": "A",
"label": "Lorem ipsum",
"value": 10
},
{
"id": 14,
"type": 2,
"name": "B",
"label": "Lorem ipsum",
"value": 20
}
]
}
}
In the code I access the values using $screen = /*object*/; $screen->parameters->values.
Is there a fast way to check if the values of answer A and B are filled in? I tought something like this:
if(isset(A) && isset(B)) { ... }
For those who are interested, I use laravel 5, maybe there is a method for it?
It looks like I need an foreach, but I rather avoid those in this case...
Nope, not with the current structure. You could however change the structure a bit to support this. You could use an object instead of an array and use the name as keys:
{
"screen": 1,
"parameters": {
"title": "Fill in the form:",
"values": {
"A":{
"id": 13,
"type": 2,
"label": "Lorem ipsum",
"value": 10
},
"B":{
"id": 14,
"type": 2,
"label": "Lorem ipsum",
"value": 20
}
]
}
}
You could then use your isset method.
isset( $screen->parameters->values->A );
You can still loop over the values as you can turn this whole thing in an associative array by passing true to json_decode as a second parameter. I for one am not a big fan of my own answer, and would probably just loop the thing, but it may still answer your question.
edit: I forgot that if you add true to json_decode, you also access your properties like this:
isset( $screen['parameters']['values']['A'] );

Processing a JSON response from TFL api using PHP?

I am trying to get certain information from the following JSON response from an API. This is the actual API call.
{
"$type": "Tfl.Api.Presentation.Entities.PlacesResponse, Tfl.Api.Presentation.Entities",
"centrePoint": [
51.555,
0.059
],
"places": [{
"$type": "Tfl.Api.Presentation.Entities.StopPoint, Tfl.Api.Presentation.Entities",
"naptanId": "490009219W",
"indicator": "Stop B",
"stopLetter": "B",
"modes": [
"bus"
],
"icsCode": "1009219",
"stopType": "NaptanPublicBusCoachTram",
"stationNaptan": "490G00009219",
"lines": [{
"$type": "Tfl.Api.Presentation.Entities.Identifier, Tfl.Api.Presentation.Entities",
"id": "25",
"name": "25",
"uri": "/Line/25",
"type": "Line"
}, {
"$type": "Tfl.Api.Presentation.Entities.Identifier, Tfl.Api.Presentation.Entities",
"id": "86",
"name": "86",
"uri": "/Line/86",
"type": "Line"
}, {
"$type": "Tfl.Api.Presentation.Entities.Identifier, Tfl.Api.Presentation.Entities",
"id": "w19",
"name": "W19",
"uri": "/Line/w19",
"type": "Line"
}],
"lineGroup": [{
"$type": "Tfl.Api.Presentation.Entities.LineGroup, Tfl.Api.Presentation.Entities",
"naptanIdReference": "490009219W",
"stationAtcoCode": "490G00009219",
"lineIdentifier": [
"25",
"86",
"w19"
]
}],
"lineModeGroups": [{
"$type": "Tfl.Api.Presentation.Entities.LineModeGroup, Tfl.Api.Presentation.Entities",
"modeName": "bus",
"lineIdentifier": [
"25",
"86",
"w19"
]
}],
"status": true,
"id": "490009219W",
"commonName": "Little Ilford Lane",
"distance": 64.10041498232529,
"placeType": "StopPoint",
"additionalProperties": [{
"$type": "Tfl.Api.Presentation.Entities.AdditionalProperties, Tfl.Api.Presentation.Entities",
"category": "Direction",
"key": "CompassPoint",
"sourceSystemKey": "Naptan490",
"value": "W"
}, {
"$type": "Tfl.Api.Presentation.Entities.AdditionalProperties, Tfl.Api.Presentation.Entities",
"category": "Direction",
"key": "Towards",
"sourceSystemKey": "CountDown",
"value": "East Ham or Manor Park"
}],
"lat": 51.554475,
"lon": 0.059381
}]
}
I want to get the naptanId, line identifier and towards as name value pairs and print them. For example,
naptan :490009219W;
lineidentifer Whatever the values are
towards : "Eastham or manor park"
Please help me I am a beginner,
Thank you in advance
Based on your question, it seems you are only interested in the values from the first place returned, so I'll assume that in the answer.
To get the data from the API into an object structure (as opposed to the JSON string you initially get):
$data = json_decode(file_get_contents('https://api.tfl.gov.uk/Place?lat=51.555504&lon=0.0592359&radius=200&includeChildren=False&type=NaptanPublicBusCoachTram&app_id=&app_key='), true);
To get the naptanId:
$naptanId = $data['places'][0]['naptanId'];
To get the lineIdentifier, which I'll assume is the one from the first lineGroup element (not lineModeGroups, but you can change as appropriate):
$lineIdentifier = $data['places'][0]['lineGroup'][0]['lineIdentifier'];
This value will be an array.
To get the towards value is a bit more complex, because you need to filter the additionalProperties array based on a child key, then pull out the value; again I'm assuming you're only interested in the first value:
$towards = array_values(array_filter(
$data['places'][0]['additionalProperties'],
function ($property) {
return $property['key'] === 'Towards';
}
))[0]['value'];
The call to array_filter pulls out the additionalProperties element where key === 'Towards' (note this assumes case sensitivity, you could add a strtolower and change the string literal to 'towards' if you want to match case insensitively). The call to array_values is necessary to normalise the array indexes. Then we pull out the first element [0] and get its value property.
Note that the above code does not do any error checking, for example if the API call does not return any places then the first time you do $data['places'][0] it will fail. If you need to handle these cases (which you almost certainly do), then you will need to pre-check these things, e.g.:
if (!isset($data['places']) || sizeof($data['places']) === 0) {...}

fetch values from array within an array

I have a multidimensional array, i wish to extract each value from this array.
The array is stored in $data.
{"success":true,"categories":
[
{"
category_id":"C1",
"parent_id":"P1",
"name":"N1",
"categories":
[
{
"category_id":"C11",
"parent_id":"P11",
"name":"N11",
},
{
"category_id":"C12",
"parent_id":"P12",
"name":"N12",
},
],
"status":"1"
},
{
category_id":"C2",
"parent_id":"P2",
"name":"N2",
"categories":
[
{
"category_id":"C21",
"parent_id":"P21",
"name":"N21",
[
{
"category_id":"C22",
"parent_id":"P23",
"name":"N24",
}
],
"status":"2"
}
],
"status":"3"
},
]
}
I tried using
$total = $data['categories']['category_id'];
to fetch value C11
but wasn't able to do so.
can anyone tell how i can fetch all the data especially C22
You have to first use json_decode.
$array = json_decode($data, true);
Then you can access the array as you have stated.
Or loop throught the categories:
if (!empty($array)) {
foreach ($array['categories'] as $category) {
echo $category['id'];
}
}
You may have to do this recursively to loop through the categories within the categories. But it depends completely what you want to achieve. A nested loop could do the job if it is always just one level deep.
EDIT
The JSON you have provided is not quite right, I have given a corrected one below:
{
"success": true,
"categories": [
{
"category_id": "C1",
"parent_id": "P1",
"name": "N1",
"categories": [
{
"category_id": "C11",
"parent_id": "P11",
"name": "N11"
},
{
"category_id": "C12",
"parent_id": "P12",
"name": "N12"
}
],
"status": "1"
},
{
"category_id": "C2",
"parent_id": "P2",
"name": "N2",
"categories": [
{
"category_id": "C21",
"parent_id": "P21",
"name": "N21",
"categories": [
{
"category_id": "C22",
"parent_id": "P23",
"name": "N24"
}
],
"status": "2"
}
],
"status": "3"
}
]
}
There were a few trailing commas and missing quote marks.
The data is not in PHP array, its a JSON array. You have to decode it, by using json_decode() function.
That's JSON, not php multidimensional array. You can use json_decode function to read through it.

json_encode() on a multidimensional array - with string keys

I am creating an very large multidimensional array using PHP. Each object contains Name, ID, ParentID and Children. Children is an array of more objects in the same format.
It is critical I name the IDs of each object - this helps me put each object under the correct parent. (In the code below, I use 101, 102 etc.)
However, the problem I am having is when I return the array in JSON using json_encode. Each 'Children' array is being printed as an object, not an array - as shown in the JSON code below.
As I read on another SO thread here, they "are made as objects because of the inclusion of string keys" - although they are numbers, they are still strings.
{
"101": {
"ID": "101",
"ParentID": "0",
"Name": "Root One"
"Children": {
"102": {
"ID": "102",
"ParentID": "101",
"Name": "Child One"
},
"103": {
"ID": "103",
"ParentID": "101",
"Name": "Child Two",
"Children": {
"104": {
"ID": "104",
"ParentID": "103",
"Name": "Child Child One"
}
}
},
Does anyone know how to overcome this issue?
Edit: The JSON should look like this (the square brackets are important!):
[
{
"ID": "101",
"ParentID": "0",
"Name": "Root One",
"Children": [
{
"ID": "102",
"ParentID": "101",
"Name": "Child One",
"Children": [
A JSON array has no explicit indexes, it's just an ordered list. The only JSON data structure that has named keys is an object. The literal should make this quite obvious:
["foo", "bar", "baz"]
This array has no named indices and there isn't any provision to add any.
PHP conflates both lists and key-value stores into one array data type. JSON doesn't.
This is your object:
$parent=new StdClass();
$parent->ID=101;
$parent->ParentID=0;
$parent->Name='Root One';
$child1=new StdClass();
$child1->ID=1011;
$child1->ParentID=$parent->ID;
$child1->Name='Child One';
$parent->Children[]=$child1;
$child1_1=new StdClass();
$child1_1->ID=10111;
$child1_1->ParentID=$child1->ID;
$child1_1->Name='Child One One';
$child1->Children[]=$child1_1;
This is your JSON convert function:
echo json_encode($parent,JSON_PRETTY_PRINT);
and this is your object coded into JSON format:
{
"ID": 101,
"ParentID": 0,
"Name": "Root One",
"Children": [
{
"ID": 1011,
"ParentID": 101,
"Name": "Child One",
"Children": [
{
"ID": 10111,
"ParentID": 1011,
"Name": "Child One One"
}
]
}
]
}
The answer came later because I started learning PHP later. Anyway, some day, someone might find it useful.
I have now got a working solution which is fast and works well.
Firstly, as written in SO link from the question;
In JSON, arrays only have numeric keys, whereas objects have string
properties. The inclusion of a array key forces the entire outer
structure to be an object by necessity.
In JSON; Curly braces hold objects ({}), Square brackets hold arrays ([]).
So using a string as a key will result in the json_encode function returning objects, whereas reseting the keys will ensure it creates arrays.
Therefore, just before I return my JSON encoded string, I run a function to reset all the array keys. The code I found on this SO thread (Reset array keys in multidimensional array) was particularly useful!
http://php.net/manual/en/function.json-decode.php
Set 2nd parameter of json_decode to true to atleast get assoc arrays.
Aside from that: javascript can't handle non-sequential/non-contiguous array indexes, so as soon as the id's are not sequential, json has no other option then to convert it into "string" indexes.

Categories