Remove instance of square brackets, if found two successive instances - php

I have a data in following manner:
{"id": "sugarcrm", "text": "sugarcrm", "children": [ [ { "id": "accounts", "text": "accounts", "children": [ { "id": "id", "text": "id" }, { "id": "name", "text": "name" } ] } ] ] }
Now, I want to remove the instance of square bracket i.e. [ and ] if there are two successive instances like this [ [ or ] ].
Now if you see the above data, you'll get to see that there are instances of [ and ] which are repeated twice successively. So I want to remove one instance of each.
Now, I can check the two successively repeated instances of each and remove one, like this
$text = '{"id": "sugarcrm", "text": "sugarcrm", "children": [ [ { "id": "accounts", "text": "accounts", "children": [ { "id": "id", "text": "id" }, { "id": "name", "text": "name" } ] } ] ] }';
echo preg_replace('/\[ \[+/', '[', $text);
Now, the above code is for [. So to remove the successively repeated instance of ], I'll have to repeat the same code again.
I want to know, is there a better way to achieve the same result or not. Meanwhile, I can work it out, but still what if, in future, I'll have to do the same for any other character? Kindly guide me here.

You are processing a json string. It is contraindicated to attempt string manipulations (with regex or other) because there are very possible pitfalls with "over-matching".
While I don't fully understand the variability of your data structure, I can provide some temporary guidance by converting your json string to an array and then safely modifying the data with an array function.
Consider this:
Code: (Demo)
$json='{"id": "sugarcrm", "text": "sugarcrm", "children": [ [ { "id": "accounts", "text": "accounts", "children": [ { "id": "id", "text": "id" }, { "id": "name", "text": "name" } ] } ] ] }';
$array=json_decode($json,true); // convert to array
foreach($array as &$a){ // $a is modifiable by reference
if(is_array($a) && isset($a[0]) && isset($a[0][0])){ // check if array and if two consecutive/nested indexed subarrays
$a=array_column($a,0); // effectively shift deeper subarray up one level
}
}
$json=json_encode($array);
echo $json;
Output:
{"id":"sugarcrm","text":"sugarcrm","children":[{"id":"accounts","text":"accounts","children":[{"id":"id","text":"id"},{"id":"name","text":"name"}]}]}
For that matter, if you know where the double-nested-indexes are, then you can access them without looping (or modifying by reference) like this:
$json='{"id": "sugarcrm", "text": "sugarcrm", "children": [ [ { "id": "accounts", "text": "accounts", "children": [ { "id": "id", "text": "id" }, { "id": "name", "text": "name" } ] } ] ] }';
$array=json_decode($json,true);
$array['children']=array_column($array['children'],0); // modify 2 known, nested, indexed subarrays
$json=json_encode($array);
echo $json;

How about:
echo str_replace(array('[ [', '] ]'), array('[', ']'), $text);

Related

php echo from a start point to a end point

I have built a php site that takes code from a page using GET, and then echos it to the current page, but it exports text like this,
{ "selection13": [ { "name": "L" }, { "name": "100%\nA" } ], "selection7": [ { "name": "S" }, { "name": "100%\nA" } ], "selection8": [ { "name": "SS" }, { "name": "100%\nA" } ], "selection9": [ { "name": "SP" }, { "name": "100%\nA" } ], "selection10": [ { "name": "P" }, { "name": "100%\nA" } ], "selection11": [ { "name": "A" }, { "name": "100.00%\nA+" } ], "selection12": [ { "name": "H", "selection5": [ { "name": "T }, { "name": "100.00%\nA+" } ] }, { "name": "100.00%\nA+", "selection5": [ { "name": "T" }, { "name": "100.00%\nA+" } ] } ] }
I need to organizes it in to categorizes like, {L},{100%), here is the code I am currently using,
<?php
$params = http_build_query(array(
"api_key" => "()",
"format" => "json"
));
$result = file_get_contents(
'(url)'.$params,
false,
stream_context_create(array(
'http' => array(
'method' => 'GET'
)
))
);
echo gzdecode($result);
?>
Your script is outputting JSON but there appears to be a few issues with the data itself that need to be addressed first.
The next to the last "name": "T is missing a closing quote.
Section 12 has an inconsistent organization compared to the other sections. Can a section be a child of another section or is this an error?
"selection11": [
{
"name": "A"
},
{
"name": "100.00%\nA+"
}
],
"selection12": [
{
"name": "H",
"selection5": [
{
"name": "T"
},
{
"name": "100.00%\nA+"
}
]
},
{
"name": "100.00%\nA+",
"selection5": [
{
"name": "T"
},
{
"name": "100.00%\nA+"
}
]
}
]
These 2 issues need to be fixed in the JSON data you are retrieving first.
From there, the best way to reorganize this is to convert it to an array using json_decode.
$json = gzdecode($result);
$resultArray = json_decode($json);
I can't tell from your question exactly how you want to reorganize the data but use one or more of the builtin array functions to get the data in the structure you want. If you need to output it in JSON, use json_encode on the manipulated array to get the final data format. More specific help can be provided if you can be more clear on want output structure you are looking for and the format (does it need to be JSON or something else).

PHP json_encode string key as array

i write a api for my games to get achievements and so on. i load the data from a webserver into unity c# over a www request. i need a array from php which contain achievements and more data. the problem is, the result is this
[
{"ID":"1",
"gameID":"1",
"name":"achv1",
"neededvalue":"50",
"player_achievements":{
"ID":"8",
"achievementID":"1",
"playerID":"9",
"value":"",
"completed":""
}
},
{"ID":"2",
"gameID": "1",
"name":"achv2",
"neededvalue":"100",
"player_achievements":{
"ID":"9",
"achievementID":"2",
"playerID":"9",
"value":"","completed":""
}
}
]
the player_achievements is a child array of the head array and i need the square_brackets around the player_achievements [] because untity c# cannot convert it to an object. i search hours for finding a solution but nobody explain how. i found this link but this is not a option for me. i want the string keys and not numbers. give it a way to use the string keys as array and not as object ?
i need it like so:
[
{ "ID":"1",
"gameID":"1",
"name":"achv1",
"neededvalue":"50",
"player_achievements":[
{ "ID":"8",
"achievementID":"1",
"playerID":"9",
"value":"",
"completed":""
}
]
},
{
"ID":"2",
"gameID":"1",
"name":"achv2",
"neededvalue":"100",
"player_achievements":[
{ "ID":"9",
"achievementID":"2",
"playerID":"9",
"value":"",
"completed":""
}
]
}
]
If I am reading your question correctly, you need to make the player_achievements element an array containing the original value of that element.
<?php
$json = <<<END
[
{"ID":"1",
"gameID":"1",
"name":"achv1",
"neededvalue":"50",
"player_achievements":{
"ID":"8",
"achievementID":"1",
"playerID":"9",
"value":"",
"completed":""
}
},
{"ID":"2",
"gameID": "1",
"name":"achv2",
"neededvalue":"100",
"player_achievements":{
"ID":"9",
"achievementID":"2",
"playerID":"9",
"value":"","completed":""
}
}
]
END;
$data = json_decode($json, true);
for($i=0;$i<sizeof($data);$i++)
{
$data[$i]['player_achievements'] = [$data[$i]['player_achievements']];
}
echo json_encode($data);
This produces a structure like the one you say you need.
[
{
"ID": "1",
"gameID": "1",
"name": "achv1",
"neededvalue": "50",
"player_achievements": [
{
"ID": "8",
"achievementID": "1",
"playerID": "9",
"value": "",
"completed": ""
}
]
},
{
"ID": "2",
"gameID": "1",
"name": "achv2",
"neededvalue": "100",
"player_achievements": [
{
"ID": "9",
"achievementID": "2",
"playerID": "9",
"value": "",
"completed": ""
}
]
}
]
I found an answer, I add a zero before the child element as key of array.

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.

FuelPHP + JSON + Ajax

For example, when I use Model_Trabalhos::query()->related('categoria'), I Get a normal JSON like this:
{
"id": "1",
"categoria_id": "2",
"empresa": "Veja",
"nome": "Veja",
"thumb_pequena": "jobs/digital/veja/thumb.jpg",
"thumb_grande": "jobs/digital/veja/thumb_grande.jpg",
"destaque": "0",
"categoria": {
"id": "2",
"titulo": "Digital"
},
"imagens": {
"1": {
"id": "1",
"url": "jobs/digital/veja/1.png",
"legenda": "",
"job_id": "1"
},
"2": {
"id": "2",
"url": "jobs/digital/veja/2.png",
"legenda": "",
"job_id": "1"
}
}
}
instead, I wanted to receive back this:
[
{
"id": "3",
"categoria_id": "2",
"empresa": "Valor Econômico",
"nome": "Novo Site",
"thumb_pequena": "jobs/digital/valor-economico/thumb.jpg",
"thumb_grande": "jobs/digital/valor-economico/thumb_grande.jpg",
"destaque": "1",
"categoria": {
"id": "2",
"titulo": "Digital"
},
"imagens": [
{
"id": "3",
"url": "jobs/digital/valor-economico/1.png",
"legenda": "",
"job_id": "3"
}
]
}
]
You see? In the second case, it's wrapped in an array, and I wanted to know if there's a function in FuelPHP native that wrap the content to be ordered.
I'm in trouble... I'm using FuelPHP + ORM to get all my records from a database and generating a JSON to use with JavaScript and Ajax, but in Chrome, the JSON is not following the order by defined, is there any workaround for this problem?
If you're wanting your information in a certain way you could follow that query with a foreach loop that would add them to an array of arrays (translated to an array of JSON objects) once converted to JSON.
$query = Model_Trabalhos::query()->related('categoria')
$categories = array();
foreach ($query as $category) {
$categories[] = array(
'id' => $category->id,
...
);
}
return $categories;
It's an old question, but i had the same problem now and colud resolve like the answer that i posted in https://stackoverflow.com/a/34242106/5670195.
In case it is a function that converts into simple array, the objects returned as the relationship of ORM.

Categories