PHP Json response formatting - php

I have the following script that returns a json response.
$response["customer_creds"] =array(array('customer_names'=>$user['name'], 'customer_email' => $user['email'], 'customer_id' => $user['customer_id'], 'customer_type' => $user['customer_type'], 'rating' => $user['rating']));
The above script returns:
"customer_creds": [
{
"customer_names": "John Doe",
"customer_email": "example#example.com",
"customer_id": "123456",
"customer_type": "1",
"rating": "4"
}
],
Now I want my json to return the customer_type as an object.("customer_type": [1],
I have tried json decoding and encoding on the same script but nothing seems to work. Any workarounds on this? At a later stage I'll want to have my json to return multiple customer types. The final response should be something like this:
"customer_creds": [
{
"customer_names": "John Doe",
"customer_email": "example#example.com",
"customer_id": "123456",
"customer_type": [1,2,3],
"rating": "4"
}
],
Any suggestion would be highly appreciated. Thanks

You just want the customer_type to be an array of values, instead of just one value?
$response["customer_creds"] = array(
array(
'customer_names' => $user['name'],
'customer_email' => $user['email'],
'customer_id' => $user['customer_id'],
'customer_type' => array($user['customer_type']), // Just wrap it with array()
'rating' => $user['rating']
)
);

Related

Laravel unit testing json response

I have the following test in my app. However the response isn't passing the test, and I can't see why...
public function test_get()
{
$user = $this->signInAsUser();
$product = factory('App\Models\Product')->create();
factory('App\Models\Stock')->create([
'product_id' => $product->id,
'qty' => $qty = rand(1, 100),
]);
$this->json('GET', '/api/stock', , ['Accept' => 'application/json'])
->assertStatus(200)
->assertJson([
'data' => [
'product_id' => "$product->id",
'stock' => "$qty"
]
]);
}
This produces the following from PHPUnit:
Unable to find JSON:
[{
"data": {
"product_id": "1",
"stock": "55"
}
}]
within response JSON:
[{
"data": [
{
"product_id": "1",
"stock": "55"
}
]
}].
Failed asserting that an array has the subset Array &0 (
'data' => Array &1 (
'product_id' => '1'
'stock' => '55'
)
).
The assertion is failing the test and I can't see why as the JSON looks the same to me...
You're asserting your JSON response is a single object, whereas it is an array of objects. Try using assertJsonFragment rather than assertJson.

How to delete a nested array inside of an array

I have an multidimensional array made out of form data that can look like this example:
array [
"absender" => "Maxim Ivan",
"email" => "maximivan#example.com",
"telefon" => "1234567890",
"fax" => null,
"grund" => "Gehaltserhöhung",
"termin" => [
0 => [
"person" => "Some Name",
"meeting" => "10.05"
],
1 => [
"person" => "Another Name",
"meeting" => "18.05"
],
2 => [
"person" => "Again another name",
"meeting" => null,
"next-possible-meeting" => "1"
],
3 => [
"person" => "And again",
"meeting" => null,
"next-possible-meeting" => "1"
],
4 => [
"meeting" => null,
],
"bemerkung" => "some notes by Maxim"
]
'person' and 'next-possible-meeting' are checkboxes while 'meeting' is a textarea. I only need the 'termin'-data when 'person' exists, so I store each of them in different arrays (one for persons, one for meetings and one for next-possible-meetings).
That means I don't need the array to be nested anymore, the 'termin' can (and should) be deleted out of it. But I don't know how to access the nested array correctly.
How do I delete the whole 'termin'-array out of the whole array and therefore make it a normal and not a multidimensional array?
Use unset()
if(isset($array['termin'])){
unset ($array['termin']);
}
Output:- https://3v4l.org/1Yj4F
Note:- isset() used to check that index exist or not, if not function call will saved.

json_encode, associative array needed in [ brackets ]

I'm using PHP, and in order to feed some data to an API using Curl, I need to format some strings and have been using json_encode. It works just fine for simpler bits, but this I can't figure out:
The API expects this:
{
"id": "string",
"startTime": "2017-04-18T08:04:23.167Z",
"endTime": "2017-04-18T08:04:23.167Z",
"contacts": [
{
"id": "string",
"displayName": "string"
}
My code so far:
$data_set_pre = array(
"id" => "",
"startTime" => "2017-04-14T07:47:59.028Z",
"endTime" => "2017-04-15T07:47:59.028Z",
"contacts" => array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"),
);
$data_set = json_encode($data_set_pre);
Unfortunately, this produces:
{"id":"","startTime":"2017-04-14T07:47:59.028Z","endTime":"2017-04-15T07:47:59.028Z","contacts":{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}}
I've been researching, and I'm getting the impression that json_encode will encode everything BUT an unbroken sequential array starting from 0 as an object, and I don't now how to work around this.
(No, I can't change what the API requires, it's provided by a 3rd-party).
<?php
$data_set_pre = array(
"id" => "12",
"startTime" => "2017-04-14T07:47:59.028Z",
"endTime" => "2017-04-15T07:47:59.028Z",
"contacts" => array(
array(
"id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"
)
)
);
$data_set = json_encode($data_set_pre);
Change the following line:
"contacts" => array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe"),
to
"contacts" => array(array("id" => "ahashofsomenumbersandletters", "displayName" => "John Doe")),
It will give:
{"id":"","startTime":"2017-04-14T07:47:59.028Z","endTime":"2017-04-15T07:47:59.028Z","contacts":[{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}]}
here [{"id":"ahashofsomenumbersandletters","displayName":"John Doe"}] is a multi-dimension array

Join more than one field using aggregate $lookup

I need to join more than two fields in two collections using aggregate $lookup. is it possible to join? please let me know if it is possible. Here i have two collections:
For Example:
"people" collections fields "city,state,country" in "country" collection fields "city_id,state_id,country_id", I want to join this three fields in following collections.
"People"
{
"_id" : 1,
"email" : "admin#gmail.com",
"userId" : "AD",
"userName" : "admin",
"city" : 1,
"state" : 1,
"country" : 1
}
"country"
{
"country_id" : 1,
"userId" : "AD",
"phone" : "0000000000",
"stateinfo":[{
"state_id" : 1,
"state_name" : "State1"
},{
"state_id" : 2,
"state_name" : "State2"
}
],
"cityinfo":[{
"city_id" : 1,
"city_name" : "city1"
},{
"city_id" : 2,
"city_name" : "city2"
}
]
}
This is probably a lot more simple than you think, considering that of course all of the "three" fields are contained within the one "country" document. So it's just a matter of doing the $lookup by "country_id" and then using the retrived content to populate the other fields.
var pipeline = [
{ "$lookup": {
"from": "country",
"localField": "country",
"foreignField": "country_id",
"as": "country"
}},
{ "$project": {
"email": 1,
"userId": 1,
"userName": 1,
"country": {
"$arrayElemAt": [
{ "$filter": {
"input": {
"$map": {
"input": "$country",
"as": "country",
"in": {
"country_id": "$$country.country_id",
"userId": "$$country.userId",
"phone": "$$country.phone",
"stateInfo": {
"$arrayElemAt": [
{ "$filter": {
"input": "$$country.stateInfo",
"as": "state",
"cond": { "$eq": [ "$$state.state_id", "$state" ] }
}},
0
]
},
"cityinfo": {
"$arrayElemAt": [
{ "$filter": {
"input": "$$country.cityinfo",
"as": "city",
"cond": { "$eq": [ "$$city.city_id", "$city" ] }
}},
0
]
}
}
}
},
"as": "country",
"cond": { "$eq": [ "$$country.userId", "$userId" ] }
}},
0
]
}
}}
]
db.people.aggregate(pipeline)
That should give you a result like:
{
"_id" : 1,
"email" : "admin#gmail.com",
"userId" : "AD",
"userName" : "admin",
"country" : {
"country_id" : 1,
"userId" : "AD",
"phone" : "0000000000",
"stateinfo": {
"state_id" : 1,
"state_name" : "State1"
},
"cityinfo": {
"city_id" : 1,
"city_name" : "city1"
}
}
So once the array is matched in by $lookup it all comes down to using $filter to do the matcing and $arrayElemAt to get the first match from each filtered array.
Since the outer array has "inner" arrays, you want to use $map for the "outer" source and apply $filter to each of it's "inner" arrays.
You can get more fancy with $let to get that "reduced" array content down to the returned sub-document and then just directly reference the resulting properties for an even "flatter" response, but the general concept of "matching" the array elements remains the same as above.
For a PHP structure translation:
$pipeline = array(
array(
'$lookup' => array(
'from' => 'country',
'localField' => 'country'
'foreignField' => 'country_id',
'as' => 'country'
)
)
array(
'$project' => array(
'email' => 1,
'userId' => 1,
'userName' => 1,
'country' => array(
'$arrayElemAt' => array(
array(
'$filter' => array(
'input' => array(
'$map' => array(
'input' => '$country',
'as' => 'country',
'in' => {
'country_id' => '$$country.country_id',
'userId' => '$$country.userId',
'phone' => '$$country.phone',
'stateInfo' => array(
'$arrayElemAt' => array(
array(
'$filter' => array(
'input' => '$$country.stateInfo',
'as' => 'state',
'cond' => array( '$eq' => array( '$$state.state_id', '$state' ) )
)
),
0
)
),
'cityinfo' => array(
'$arrayElemAt' => array(
array(
'$filter' => array(
'input' => '$$country.cityinfo',
'as' => 'city',
'cond' => array( '$eq' => array( '$$city.city_id', '$city' ) )
)
),
0
)
)
}
)
),
'as' => 'country',
'cond' => array( '$eq' => array( '$$country.userId', '$userId' ) )
)
),
0
)
)
)
)
);
$people->aggregate($pipeline);
You can usually check your PHP matches a JSON structure when you are working from a JSON example by dumping the pipeline structure:
echo json_encode($pipeline, JSON_PRETTY_PRINT)
And that way you cannot go wrong.
As another final note here, the process after the $lookup is done is quite "complex" even if very efficient. So I would advise that unless there is some need to take this aggregation pipeline further and actually "aggregate" something, then you are probably better off doing that "filtering" in client code rather than doing it on the server.
The client code to do the same thing is far less "obtuse" than what you need to tell the aggregation pipeline to do. So unless this "really" saves you a lot of bandwidth usage by reducing down the matched array, or indeed you if can just "lookup" by doing another query instead, then stick with doing it in code and/or do the seperate query.

Passing array to an API

i am trying to pass an array to an API, the API takes array in following format when i run it in POSTMAN (raw form),
{
"records": [
{
"content": "50.150.50.55",
"type": "A",
"name": "test.mauqe.com",
"prio": null,
"ttl": 3600
}
]
}
while am trying to pass the array in my code in this format,
$data = array(
"content" => "50.150.50.55",
"type" => "A",
"name" => "gulpanra.mauqe.com",
"prio" => "null",
"ttl" => "3600"
);
i don't understand, whats the problem. response said error (Data sending format error). plz help
The API expects an array of maps. The following is an array of maps.
[
{
"content": "50.150.50.55",
"type": "A",
"name": "test.mauqe.com",
"prio": null,
"ttl": 3600
},
{},
{},
...
]
What you are passing is not the same. You're passing in a single map
{
"content" => "50.150.50.55",
"type" => "A",
"name" => "gulpanra.mauqe.com",
"prio" => "null",
"ttl" => "3600"
}
Try amending $data to:
$data = array();
array_push($data['records'], array(
"content" => "50.150.50.55",
"type" => "A",
"name" => "gulpanra.mauqe.com",
"prio" => "null",
"ttl" => "3600"
));
<?php
$data = array('records' => array());
$data['records'][] = array(
"content" => "50.150.50.55",
"type" => "A",
"name" => "gulpanra.mauqe.com",
"prio" => null,
"ttl" => 3600
);
$json_output = json_encode( $data );
echo $json_output;
?>
This will give the following as output:
{"records":[{"content":"50.150.50.55","type":"A","name":"gulpanra.mauqe.com","prio":null,"ttl":3600}]}
Use json_encode to convert your array in json format and then pass it to the api.
The Api you are using is expecting data in json format.
$data = json_encode($data);
You will need to convert array into json format in order to pass it to the api. use json_encode(). Use the code below
$array = array( "content" => "50.150.50.55", "type" => "A", "name" => "gulpanra.mauqe.com", "prio" => "null", "ttl" => "3600" );
$data = json_encode($data); // Pass this to API
Hope this helps you
you have to make array outside for example
you are using this type of array to encode
$data['records'] = array(
'content' => '50.150.50.55',
and so on
);
change this array to this
$data = array(
'content' => '50.150.50.55',
and so on
);
this will help

Categories