How can I create a json file from object with serializer? - json

This is my object $input:
$input = $this->em->getRepository(Data::class)->findAll();
foreach($input as &$arr){
$arr->{"Sunshine"} = 'Clouds';
}
The output of $input:
Data {#1523 ▼
-id: 23
-name: "cat"
-timestamp: DateTime #1570445917 {#1517 ▶}
+"Sunshine": "Clouds"
}
I am using serializer to create a JSON file $data
// Serialize your object in JSON
$context = [
'circular_reference_handler' => function ($object) {
return $object->getId();
},
'circular_reference_limit' => 0,
];
$data = $serializer->serialize($input, 'json', $context);
$data:
"[{"id":21,"name":"cat","timestamp":"07.10.2019"}] ◀"
I wonder, why "Sunshine" is not in the JSON file. Does it have something to do with the +? What does + mean?

I think you're assigning the key incorrectly. A key should be assigned like this:
$arr['keyName'] = $value
You're assigning it like this:
$arr->{"keyName"} = $value
I hope I helped you with this answer!

Related

how to convert array from postgres db to array variable in laravel?

how to convert array from postgres db to array variable in laravel ?
my postgres array structure
i have result var_dump from laravel :
0 => array:1 [
"order_itemset" => "{8,11}"
]
1 => array:1 [
"order_itemset" => "{8,12}"
]
2 => array:1 [
"order_itemset" => "{17,10}"
]
]
how i can get the data and store the data to array variable?
like this
$data = [['8', '11'], ['8', '12'], ['17', '10']];
sorry for my broken english ,thanks.
Take a look here.
You can simplify this code if your postgres query returns an array "[8,11]" instead of a "sort-of" JSON "{8,11}"
<?php
$values = array_column($your_data, 'order_itemset');
$values = array_map(function ($v) {
preg_match("/^\{(.+)\}$/", $v, $matches);
if ($matches[1]) {
return explode(',', $matches[1]);
}
return null;
}, $values);
print_r($values);
you can use foreach
$original_array = $your_array; //Your base array that you showed us on your Question
$base_array = array();
foreach($original_array as $original)
{
$child_array = array();
foreach($original->order_itemset as $a)
{
$child_array[] = $a;
}
$base_array[] = $child_array;
unset($child_array);
}
die($base_array);

How to save data json from api external to database in laravel

i want to generate reports from api external, using guzzle, here is my result
{#430 ▼
+"data": {#427 ▼
+"report_id": "20190801-5f6e21a5"
+"status": 5
+"creation_date": "2019-08-01 13:19:49"
+"due_date": "2019-08-02 13:19:49"
+"data": {#432 ▼
+"chassis_number": "ACR50-0183692"
+"engine": "2AZFE"
+"manufacture_date": "2014-07"
+"registration_date": "2019-04-17"
+"make": "TOYOTA"
+"model": "ESTIMA"
+"displacement": "2360"
+"fuel": "GASOLINE"
}
}
+"error": ""
}
but i dont know how to get the value from this json and save to database. i want to save value from report_id, status, creation date etc
$client = new Client();
$body = $client->request('GET', 'https://xxxxx/api/v1/get-report', [
'headers' => [
'Accept' => 'application/json',
'Carvx-User-Uid' => 'xxxxxx',
'Carvx-Api-Key' => 'xxxxxx',
'needSignature' => '0',
'raiseExceptions' => '1',
'isTest' => '0'
],
'query' => [
'report_id' => $reportId,
'true'=>'1'
]
])->getBody();
$contents = (string) $body;
$data = json_decode($contents);
// dd($data);
//to get value from status
$var_status = var_export($data['status'],true);
$status = substr($var_status, 1, -1);
echo $status;
and i get this error
Cannot use object of type stdClass as array
json_decode by default returns a Stdclass object, with properties representing the keys in the json object.
You can tell json_decode to return an associative array instead by passing true as the second param:
json_decode($contents, true); // returns array
Docs: https://www.php.net/manual/en/function.json-decode.php

How to create associative array in Yii2 and convert to JSON?

I am using a calendar in my project and I want to pass data from my Event model to view file in JSON format. I tried following but it didn't work and am not able to display the data properly
$events = Event::find()->where(1)->all();
$data = [];
foreach ($events AS $model){
//Testing
$data['title'] = $time->title;
$data['date'] = $model->start_date;
$data['description'] = $time->description;
}
\Yii::$app->response->format = 'json';
echo \yii\helpers\Json::encode($data);
But it only returns one model in that $data array, the final data should be in following format:
[
{"date": "2013-03-19 17:30:00", "type": "meeting", "title": "Test Last Year" },
{ "date": "2013-03-23 17:30:00", "type": "meeting", "title": "Test Next Year" }
]
When you write this:
\Yii::$app->response->format = 'json';
before rendering data, there is no need to do any additional manipulations for converting array to JSON.
You just need to return (not echo) an array:
return $data;
An array will be automatically transformed to JSON.
Also it's better to use yii\web\Response::FORMAT_JSON constant instead of hardcoded string.
Another way of handling that will be using ContentNegotiator filter which has more options, allows setting of multiple actions, etc. Example for controller:
use yii\web\Response;
...
/**
* #inheritdoc
*/
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['view', 'index'], // in a controller
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
];
}
It can also be configured for whole application.
Update: If you are using it outside of controller, don't set response format. Using Json helper with encode() method should be enough. But there is also one error in your code, you should create new array element like this:
$data = [];
foreach ($events as $model) {
$data[] = [
'title' => $time->title,
'date' => $model->start_date,
'description' => $time->description,
];
}
You can try like this:
$events = Event::find()->select('title,date,description')->where(1)->all()
yii::$app->response->format = yii\web\Response::FORMAT_JSON; // Change response format on the fly
return $events; // return events it will automatically be converted in JSON because of the response format.
Btw you are overwriting $data variable in foreach loop you should do:
$data = [];
foreach ($events AS $model){
//Make a multidimensional array
$data[] = ['time' => $time->title,'date' => $model->start_date,'description' => $time->description];
}
echo \yii\helpers\Json::encode($data);

encoding json with no quote around numerical values

I have a perl code snippet
use JSON::XS;
$a = {"john" => "123", "mary" => "456"};
print encode_json($a),"\n";
The output is
{"john":"123","mary":"456"}
Wonder if there is an option to cause encode_json function (from JSON::XS module) to encode it so that the values (123, 456) are not surrounded by double-quote. i.e., like
{"john":123,"mary":456}
Unfortunately I can't change the hash in $a because it's passed to me from another function. Wonder if there is any trick on encode_json().
Thanks!
You probably need to preprocess the data yourself, prior to JSON serialization.
This solution uses Data::Leaf::Walker to traverse an arbitrary structure, converting strings to numbers.
use JSON;
use Data::Leaf::Walker;
use Scalar::Util qw();
my $a = {"john" => "123",
"mary" => ["456","aa"],
"fred" => "bb",
"nested" => {"Q" => undef, "A" => 42},
};
my $walker = Data::Leaf::Walker->new( $a );
while (my ( $key_path, $value ) = $walker->each ) {
$walker->store($key_path, $value + 0)
if Scalar::Util::looks_like_number $value;
};
print to_json($a);
Output: {"john":123,"nested":{"A":42,"Q":null},"mary":[456,"aa"],"fred":"bb"}
You shouldn't use JSON::XS directly, just JSON will already load JSON::XS if available.
A scalar in Perl is tagged whether it is a string or a number, and here you're providing strings. Remove the quotes from your numbers, and they should show up unquoted as JSON already does that automatically.
If you're reading strings (from say a database) then you can coerce the strings to numbers like this:
{ john => 0+$john, mary => 0+$mary }
Update, here's a recursive replacement:
#!/usr/bin/env perl
use JSON;
use Modern::Perl;
use Scalar::Util qw( looks_like_number );
my $structure = {
john => "123",
mary => 456,
deeper => {
lucy => "35zz",
names => [
"john",
"123",
456,
],
},
};
sub make_numbers_recursively {
my ( $data ) = shift;
if ( ref $data eq 'HASH' ) {
# Replace hash values with recurisvely updated values
map { $data->{ $_ } = make_numbers_recursively( $data->{ $_ } ) } keys %$data;
} elsif ( ref $data eq 'ARRAY' ) {
# Replace each array value with recursively processed result
map { $_ = make_numbers_recursively( $_ ) } #$data;
} else {
$data += 0 if looks_like_number( $data );
}
return $data;
}
my $json = JSON->new->pretty;
say $json->encode( $structure );
make_numbers_recursively( $structure );
say $json->encode( $structure );
This outputs:
{
"mary" : 456,
"deeper" : {
"names" : [
"john",
"123",
456
],
"lucy" : "35zz"
},
"john" : "123"
}
{
"mary" : 456,
"deeper" : {
"names" : [
"john",
123,
456
],
"lucy" : "35zz"
},
"john" : 123
}
Beware that it modifies the structure in-place, so if you need the original data for anything you might want to Clone or Data::Clone it first.

JSON formatting in Perl

I am trying to create a JSON object that lists maps associated to a particular user, but haven't ever worked with nested JSON objects. This is what I want:
{
"success":"list of users maps",
"maps":[
{
"id":"1",
"name":"Home to LE",
"date_created":"1366559121"
},
{
"id":"2",
"name":"Test 1",
"date_created":"1366735066"
}
]
}
with this perl code:
my $maps = [];
for (my $x = 0; $x < $sth->rows; $x++) {
my ($id, $name, $date) = $sth->fetchrow_array();
my $map = qq{{"id":"$id","name":"$name","date_created":"$date"}};
push $maps, $map;
}
my $j = JSON::XS->new->utf8;
my $output = $j->encode({
"success"=>"list of users maps",
"maps"=>$maps
});
But the output I am getting is:
{
"success":"list of users maps",
"maps":[
"{\"id\":\"1\",\"name\":\"Home to LE\",\"date_created\":\"1366559121\"}",
"{\"id\":\"2\",\"name\":\"Test 1\",\"date_created\":\"1366735066\"}"
]
}
So when I process it in my Javascript, the data.maps[x].id is undefined. I am pretty sure that the JSON being output is incorrectly formatted.
Can anyone help me fix it?
It's undefined because what you have at data.maps[x] is not an object, but a string. Since a string has no property called id, you're getting undefined. I'd probably do something like this (if I couldn't change the perl script):
var mapData = JSON.parse(data.maps[x]);
//do stuff with mapData.id
But the better thing to do, is to make sure that it doesn't encode it as a string, but as proper JSON.
This part in your perl script:
my $map = qq{{"id":"$id","name":"$name","date_created":"$date"}};
Is simply making a quoted string out of all that data. Instead, what you want is an actual perl hash that can be translated into a JSON map/associative-array. So try this:
my $map = {
"id" => "$id",
"name" => "$name",
"date_created" => "$date"
};
push $maps, $map;
This way you actually have a perl hash (instead of just a string) that will get translated into proper JSON.
As an example, I wrote some test code:
use strict;
use JSON::XS;
my $maps = [];
push $maps, { id => 1, blah => 2 };
push $maps, { id => 3, blah => 2 };
my $j = JSON::XS->new->utf8->pretty(1);
my $output = $j->encode({
success => "list of blah",
maps => $maps
});
print $output;
When you run this, you get:
{
"success" : "list of blah",
"maps" : [
{
"blah" : 2,
"id" : 1
},
{
"blah" : 2,
"id" : 3
}
]
}