Create JSON with Square brackets instead of curly brackets - php

Tunnelvision:
I have a pretty basic array like this:
array(1) {
["locations"]=>
array(13) {
["identifier"]=>
string(4) "0815"
["status"]=>
string(6) "ACTIVE"
["street"]=>
string(12) "Mainstreet"
}
}
What I need is a simple output in JSON in object-form like this:
{
"locations":[
{
"identifier":0815,
"status":"ACTIVE",
"street":"Mainstreet"
}
]
}
I simply can't get it formatted correctly. I tried json_encode with the 2nd, optional parameter JSON_FORCE_OBJECT like this:
var_dump(json_encode($patchObjectArray, JSON_FORCE_OBJECT));
I tried wrapping it around another array, but also without success. I always end up with having this structure:
{
"locations":{
"identifier":"0815",
"status":"ACTIVE",
"street":"Mainstreet"
}
}
I also tried to parse it into an object with (object)$patchObjectArray, also didn't work.
Wrapped another array around it like this:
array(array("locations" => $patchObjectArray)), that just led to another "0"-index, also with curly brackets
What am i missing here?

This is the data structure that will give you the required output:
echo json_encode([
"locations" => [
[
"identifier" => "0815",
"status" => "ACTIVE",
"street" => "Mainstreet"
]
]
]);
As you can see - your "locations" must be array of arrays.

$a = ['locations' => [[
'identifier' => '0815',
'status' => 'Active',
'street' => 'Mainstreet'
]]];
echo json_encode($a);

Related

Manipulate JSON node to have [] parentheses

Json response from 3rd party platform which I cant control.
$json = '{
"question1": "answera",
"question2": [
"answerb",
"answerc"]
}';
Any 'question' can have multiple 'answers', however if there is only one 'answer' for that question the response comes back without the [] parentheses - this is breaking the insert into the next system (that I also dont have control over) as it is expecting the [].
Using PHP is there a way to manipulate the json string to be the following, irrelevant of the number of 'answers':
"question1": ["answera"],
You can convert string contents into an array. But you habe to iterate over all answers for this purpose.
Creating an array with an if-condition
<?php
$json = '{
"question1": "answera",
"question2": [
"answerb",
"answerc"
]
}';
// second parameter for array result
$array = json_decode($json, true);
foreach ($array as $question => $answer) {
if (is_string($answer) === true) {
$array[$question] = [ $answer ];
}
}
This one results into ...
array(2) {
'question1' =>
array(1) {
[0] =>
string(7) "answera"
}
'question2' =>
array(2) {
[0] =>
string(7) "answerb"
[1] =>
string(7) "answerc"
}
}
For any further JSON processing you can convert the PHP array back into JSON.
$json = json_encode($array);
Results into ...
string(109) "{
"question1": [
"answera"
],
"question2": [
"answerb",
"answerc"
]
}"
Casting with (array)
Another solution taken from the comments was mentioned by #RickN. Casting with (array) avoids the if condition and could possibly be faster, if that matters for your application.
foreach ($array as $question => $answer) {
$array[$question] = (array) $answer;
}

Condition check inside foreach loop

I want to filter data where $data['stock'] != 0 from an json array. Can I put the condition check inside the foreach loop? Or, is there any better way to execute the same?
foreach($json['items'] as $data)
{
if(!$data['stock'] == 0) {
echo 'Success';
}
}
There are many ways to achieve what you want to achive. Your code is not wrong. You can also try playing with array_filter().
$json = [
"items" => [[
"name" => "Widget",
"stock" => 3
],[
"name" => "Foo",
"stock" => 0
],[
"name" => "Bar",
"stock" => 2
]]
];
$filtered_array = array_filter($json['items'], function($data){
return $data['stock'];
//Will get rid fo the Foo item because its stock is 0
});
var_dump($filtered_array);
// Will NOT contain the Foo item
Expected output:
array(2) {
[0]=>
array(2) {
["name"]=>
string(6) "Widget"
["stock"]=>
int(3)
}
[2]=>
array(2) {
["name"]=>
string(3) "Bar"
["stock"]=>
int(2)
}
}
This will filter your array to only contain those items that have a value in $data['stock']. You don't need to write != 0, because in PHP, in this particular comparison context, 0 is translated as a boolean false.
Quick demo

Correctly format JSON file

I'm trying to create a JSON file which contains objects and an array. Yet I'm missing the [ ]-brackets. I don't really know the exact terms for these JSON parts, which makes finding a solution using Google incredibly hard. I'm also a fairly new PHP coder, so I'm still learning. Any help or tips are really appreciated!
Code to create the JSON file:
$db_export = [
'account' => [
'username' => $username,
'email' => $email
]
];
file_put_contents("output.json", json_encode($db_export, JSON_PRETTY_PRINT));
Which outputs as:
{
"account": {
"username": "test",
"email": "test#domain.com"
}
}
What it's supposed to be:
{
"account": [
{
"username": "test",
"email": "test#domain.com"
}
]
}
Adding [] characters will help. This creates an array inside the array.
$db_export = [
'account' => [[ // <--- Added
'username' => $username,
'email' => $email
]] // <--- Added
];
file_put_contents("output.json", json_encode($db_export, JSON_PRETTY_PRINT));
This is how you get the result you want.
Output :
{ "account": [ { "username": null, "email": null } ] }
I guess it was a little simple :)
I am adding this to explain what is going on with the original answer. You can find this same information in the json_encode php manual page, in the example sections.
With any simple PHP array, json_encode will transform the PHP array into a JSON array:
$simple = array('apple', 'banana', 'coconut');
echo json_encode($simple);
Returns:
["apple","banana","coconut"]
Any associative array will be turned into a json object {} and each associative key will become a property name.
$associative = array('breakfast' => 'apple', 'lunch' => 'banana', 'dinner' => 'coconut');
echo json_encode($associative);
Returns:
{"breakfast":"apple","lunch":"banana","dinner":"coconut"}
In your example, you have an array with an associative key 'account' that contains an array with 2 child elements, each with an associative key.
This is the reason json_encode() is turning your structure into json objects.
In #Smokie's answer, the addition of an extra parent array that is "simple" ie. not keyed with a name, causes json_encode (following it's simple transformation rules) to create a javascript array, which it then sticks the javascript object inside of.
$username = 'test user';
$email = 'foo#bar.com';
$db_export = [
'account' => [[ // <--- Added
'username' => $username,
'email' => $email
]] // <--- Added
];
var_dump($db_export);
Returns:
array(1) {
["account"]=>
array(1) {
[0]=>
array(2) {
["username"]=>
string(9) "test user"
["email"]=>
string(11) "foo#bar.com"
}
}
}
Here I use var_dump as a quick debugging tool to show what the PHP array looks like. The important thing to note is that 'account' is now an array(1) with one element ( the 0th element) that contains your original child array.
Presumably you need this because the assumption is that an account could have multiple accountname/email address pairs. If that isn't the case, I would question why you need to force a useless array. I personally don't see how an 'account' could have multiple username/email pairs associated with it.
With that said, this code should further illustrate how this all works, and why:
$username = 'test user';
$email = 'foo#bar.com';
$db_export = [
'account' => [[ // <--- Added
'username' => $username,
'email' => $email
]] // <--- Added
];
//Add another username/email pair to account
$db_export['account'][] = ['username' => 'test2 user', 'email' => 'test2#bar.com'];
echo json_encode($db_export, JSON_PRETTY_PRINT);
Returns:
{
"account": [
{
"username": "test user",
"email": "foo#bar.com"
},
{
"username": "test2 user",
"email": "test2#bar.com"
}
]
}

PHP - MongoDB: Retrieve Fields from Sub Document with Field Names in Array

Consider an Array
$lettersArray = [A,C,E,G]
and my MongoDB Collection has the following structure.
{
Collection : {
letters:{
A:{...},
B:{...},
...
Z:{...}
}
}
}
Consider that the Letter Sub document is a part of a larger collection. Hence I am using Aggregation.
Right Now I have tried to project -
['$Collection.letters' => ['$elemMatch' => ['$in' => $lettersArray]]
and also tried
['Letters' => ['$in' => [$lettersArray,'$Collection.letters']]
But it didn't work.
In the End, I want result like the following:
[
Collection => [
letters => [
A => [...],
C => [...],
E => [...],
G => [...]
]
]
]
Is there any way to do this?
In PHP you can use array_combine with array_fill to create the empty arrays.
$lettersArray = ['A','C','E','G'];
$letters = array_combine($lettersArray, array_fill(0,count($lettersArray), []));
Array_fill creates an array from index 0, to the count of items in $lettersArray with the contents []
Output:
array(4) {
["A"]=>
array(0) {
}
["C"]=>
array(0) {
}
["E"]=>
array(0) {
}
["G"]=>
array(0) {
}
}
https://3v4l.org/TeoFv
I think you are mistaken in the way you are trying to access the documents' information.
If you take a look at your MongoDB document, you will see that it is in fact not an array, so you should not use $elemMatch to project these fields, but simple projections. In your case, you should project in this way:
[
'$project' => [
'Collection.letters.A' => 1,
'Collection.letters.C' => 1,
'Collection.letters.E' => 1,
'Collection.letters.G' => 1
]
]
By the way, you don't need to use the aggregation framework to compute such a projection. You could just use find(), and use the projection in the options, which are the functions' second argument:
myCollection->find(query, [
'projection' => [
'Collection.letters.A' => 1,
'Collection.letters.C' => 1,
'Collection.letters.E' => 1,
'Collection.letters.G' => 1
]
]);
Cheers,
Charles

update an embedded document in mongodb using php

I am making a blogging site so I am using MongoDB as my DB. In my collection "articles", I have 1 embedded doc named posts and I want to insert 1 more embedded doc. comments into it.
DB:
{
"_id": ObjectId("4f41a5c7c32810e404000000"),
"username":"abc",
"posts": [
{
"_id": 1,
"content": "dskcnkdcnksldcnskcd",
"title" : "test1"
},
{"_id": 2,
"content": "dskcsdsl;d,cl;sdcl;sdmcnkdcnksldcnskcd",
"title" : "test2"
},
]
}
I want to insert comments into posts.
{
"_id": ObjectId("4f41a5c7c32810e404000000"),
"username":"abc",
"posts": [
{
"_id": 1,
"content": "dskcnkdcnksldcnskcd",
"title" : "test1",
"comments":[
{
"content": "usdhcjsdcjskd",
"by" : "abc"
}
]
},
{"_id": 2,
"content": "dskcsdsl;d,cl;sdcl;sdmcnkdcnksldcnskcd",
"title" : "test2"
}
]
}
Comments is actually an embedded document of posts in your document as such you need to change your query a little to:
$collection->update(array('_id' => new MongoId($bid),'posts.id'=> $pid),array('$push' => array('posts.$.comments' => $comment)));
Try that.
Notice how I have used the positional operator? You can read more about it here: http://www.mongodb.org/display/DOCS/Updating/#Updating-The%24positionaloperator
the thing you need to be careful is your structure for first insert. For example you have some user with some lists and you want to let him to have up to 5 lists. This is how you can do it with PHP:
You need to install your mongodb extension if you do not have it in your PHP environment on your localhost server
You need to install mongodb and run it.
After all that is done you can easily do it like this:
$m = new Mongo("mongodb://localhost");
$db = $m->statistic->list;
// statistic is my database and list are collection.
$list =
array(
'_id' => 18,
'lists' =>
array(
array(
'name' => 'Magento and PHP developer',
'recipients' =>
array(
'name' => 'Kristijan Glibo',
'email' => 'glibo.kristijan#gmail.com'
),
'count' => 12345),
));
You can see here that I use some (int)18 for my _id. If you do not specify it, Mongo will generate it. I use it like this just for testing purposes. Notice here that lists are array and every list inside it are array too with their own data! My list Magento and PHP developer have data about recipients and count. Recipients also have some unique data.
Lets make first insert into our Mongodb:
$document = $db->insert($list);
If we now dump collection to check out what we saved inside of it we will get this:
NOTE: To get your collection and everything inside it you can use this code:
$documents = $db->find();
echo '<pre>';
foreach ($documents as $doc) {
var_dump($doc);
}die();
********************this is dumped data*******************
["_id"]=>
int(18)
["lists"]=>
array(3) {
[0]=>
array(3) {
["name"]=>
string(10) "Magento and PHP developer"
["recipients"]=>
array(2) {
["name"]=>
string(4) "Kristijan Glibo"
["email"]=>
string(25) "glibo.kristijan#gmail.com"
}
["count"]=>
int(12345)
}
Lets now update our user and add him more lists:
$updatelist = array('name' => 'updatelist', 'recipients' => array(),'count'=>2876);
$documentupdate = $db->
update(
array('_id'=>18),
array('$addToSet' => array('lists'=> $updatelist)));
You are telling him which object to update by selectin _id => 18 and how to update. I test this and it will add new list if that list do not exist. If exist it will skip it.
Hope this helps!

Categories