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).
Related
i have a nested array to validate which i looked at other questions and valited that . but my problem begins when i multiple the array like below :
{
"items": [
{
"sender": {
"firstName": "firstName",
"lastName": "lastName",
},
"items": [
{
"weight": {
"value": 1000
}
}
]
},
{
"sender": {
"firstName": "firstName",
"lastName": "lastName",
},
"items": [
{
"weight": {
"value": 1000
}
}
]
}
]
}
now what i want to do is to validate senders and value to exists and check types of them .
what i have tried so far is :
first i send the $data = $request->get('items'); to the validator and then .
public function rules()
{
return [
"sender.*.firstName" => "required|string|max:17",
but i all the time get this error on validation :
{
"detail": "",
"message": {
"sender.lastName.firstName": [
"sender.lastName.firstName is required."
],
can you please give some advice how should i validate that array ?? thanks
it's items.*.sender.firstName. You have to put the * where the array is
You should not remove items from the data.
You can try *.sender.firstName but i'm not sure if it will work, i think it needs a toplevel field
I am getting an array from an API that varies in number of levels but follows the same basic structure - here is a truncated sample as this particular repsonse is 25K lines:
{
"Rows": {
"Row": [
{
"Header": {
"ColData": [
{
"value": "Ordinary Income/Expenses"
},
{
"value": ""
}
]
},
"Rows": {
"Row": [
{
"Rows": {},
"Summary": {
"ColData": [
{
"value": "Gross Profit"
},
{
"value": ""
}
]
},
"type": "Section"
},
{
"Header": {
"ColData": [
{
"value": "Income"
},
{
"value": ""
}
]
},
"Rows": {
"Row": [
{
"Header": {
"ColData": [
{
"value": "40000 Sales Income",
"id": "31"
},
{
"value": ""
}
]
},
"Rows": {
"Row": [
{
"Rows": {
"Row": [
{
"ColData": [
{
"value": "2022-01-24"
},
{
"value": "Invoice",
"id": "148774"
},
{
"value": "208232"
},
{
"value": "Hyatt:#211102",
"id": "7568"
},
{
"value": "JN",
"id": "4100000000000368107"
},
{
"value": "CAPTIVE AIRE"
},
{
"value": "11000 Accounts Receivable",
"id": "80"
},
{
"value": "38748.00"
},
{
"value": "38748.00"
}
],
"type": "Data"
},
I need to traverse the json, and where there is data in both [Header][ColData][value] AND [Header][ColData][id] extract the value, id (in this snippet "value": "40000 Sales Income", "id": "31") and the data that immediately follows the "value"/"id" in [Rows][Row][Rows][Row][ColData] (in this snippet starting with "ColData": [{"value": "2022-01-24"...)
[Rows][Row][Rows][Row][ColData] will have one to a few hundred subarrays. I can extract the data from the subarrays once they are found - it's just managing the varying depths of the array that is warping my brain.
[Rows][Row][Rows][Summary] can be discarded as well.
I have tried multiple foreach loops - but by time I get 5 or 6 levels deep it gets very confusing. The number of Header sections varies depending on the report type. The [Rows][Row] nesting is multiple layers deep... I'm sure there has to be a better way than nesting foreach loops...
This is what I've come up with. Kindly modify it to meet your need.
$array = json_decode($json, true);
function traverse_some_array($array){
$result = [];
foreach($array['Rows']['Row'] ?? [] as $row){
if( !empty($row['Header']['ColData']) ){
foreach($row['Header']['ColData'] as $coldata){
if( isset($coldata['value'], $coldata['id']) ){
// there is data in both [Header][ColData][value] AND [Header][ColData][id]
// extract the value, id (in this snippet "value": "40000 Sales Income", "id": "31")
$extract_data = [
'value' => $coldata['value'],
'id' => $coldata['id']
];
// the data that immediately follows the "value"/"id" in [Rows][Row][Rows][Row][ColData]
$immediate_coldata = $row['Rows']['Row'] ?? [];
// you can do what ever you want with the results, eg return it or push it to a result array
$result[] = [
'extract_data' => $extract_data,
'immediate_coldata' => $immediate_coldata
];
}else{
// continue traversing the array
$result = array_merge($result, traverse_some_array($row));
}
}
}
}
return $result;
}
print_r(traverse_some_array($array));
My JSON file
{
"shopId": 29,
"last": 46977914,
"freshfood": [
{
"freshfood_id": 2629,
"food": [
{
"food_id": 1740851,
"type": "fruit",
"status": 1
},
{
"food_id": 1730905,
"type": "vegetable",
"status": 1
},
]
}
]
}
I need to get second food_id (1730905)
I try this, but it does not work.
$string = file_get_contents("food.json");
$json_a=json_decode($string,true);
echo $GetFreshFoodId = $json_a['freshfood'][1]['freshfood_id'];
$json_a['freshfood']['food'][1]['food_id'];
It´s a syntrax error in your json file.
Your last entry in "food": [ ... ] has a comma.
That´s the reason why you get NULL when you´re run json_decode
{
"shopId": 29,
"last": 46977914,
"freshfood": [
{
"freshfood_id": 2629,
"food": [
{
"food_id": 1740851,
"type": "fruit",
"status": 1
},
{
"food_id": 1730905,
"type": "vegetable",
"status": 1
},
]
}
]
}
I'm implementing ElasticSearch into my Laravel application using the php package from ElasticSearch.
My application is a small jobboard and currently my job document is looking like this:
{
"_index":"jobs",
"_type":"job",
"_id":"19",
"_score":1,
"_source":{
"0":"",
"name":"Programmer",
"description":"This is my first job! :)",
"text":"Programming is awesome",
"networks":[
{
"id":1,
"status":"PRODUCTION",
"start":"2015-02-26",
"end":"2015-02-26"
},
{
"id":2,
"status":"PAUSE",
"start":"2015-02-26",
"end":"2015-02-26"
}
]
}
}
As you can see a job can be attached to multiple networks. In my search query I would like to include WHERE network.id == 1 AND network.status == PRODUCTION.
My current query looks like this, however this returns documents where it has a network of id 1, if it has any network of status PRODUCTION. Is there anyway i can enforce both to be true within one network?
$query = [
'index' => $this->index,
'type' => $this->type,
'body' => [
'query' => [
'bool' => [
'must' => [
['networks.id' => 1]],
['networks.status' => 'PRODUCTION']]
],
'should' => [
['match' => ['name' => $query]],
['match' => ['text' => $query]],
['match' => ['description' => $query]],
],
],
],
],
];
You need to specify that the objects in the networks array should be stored as individual objects in the index, this will allow you to perform a search on individual network objects. You can do so using the nested type in Elasticsearch.
Also, if you doing exact matches it is better to use a filter rather than a query as the filters are cached and always give you better performance than a query.
Create your index with a new mapping. Use the nested type for the networks array.
POST /test
{
"mappings": {
"job": {
"properties": {
"networks": {
"type": "nested",
"properties": {
"status": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
}
}
Add a document:
POST /test/job/1
{
"0": "",
"name": "Programmer",
"description": "This is my first job! :)",
"text": "Programming is awesome",
"networks": [
{
"id": 1,
"status": "PRODUCTION",
"start": "2015-02-26",
"end": "2015-02-26"
},
{
"id": 2,
"status": "PAUSE",
"start": "2015-02-26",
"end": "2015-02-26"
}
]
}
As you have a nested type you will need to use a nested filter.
POST /test/job/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"nested": {
"path": "networks",
"filter": {
"bool": {
"must": [
{
"term": {
"networks.id": "1"
}
},
{
"term": {
"networks.status.raw": "PRODUCTION"
}
}
]
}
}
}
}
}
}
}
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.