Laravel numeric array in select results - php

I'm using Lumen to set up a microservice for polling a database frequently and distribute the dataset through a wamp router to multiple clients. The database query is stored in a stored procedure, that's why i do the following in my controller:
$result = DB::select($query);
return $result;
The return gives the following dataset:
[
{
"0": "012345",
"1": "Moby Dick",
"2": "Herman Melville",
"3": "Hardcover",
"isbn": "012345",
"title": "Moby Dick",
"author": "Herman Melville",
"type": "Hardcover"
},
{
"0": "123456",
"1": "Laravel: Code Bright",
"2": "Dayle Rees",
"3": "Ebook",
"isbn": "123456",
"title": "Laravel: Code Bright",
"author": "Dayle Rees",
"type": "Ebook"
},
{
"0": "234567",
"1": "Easy Laravel 5",
"2": "W.J. Gilmore",
"3": "Ebook",
"isbn": "234567",
"title": "Easy Laravel 5",
"author": "W.J. Gilmore",
"type": "Ebook"
}
]
I want to remove the numeric key-value pairs prepending the associative key-value pairs. How can i do that?
Thanks in advance!
Edit: things I tried:
$result = DB::select($query)->get(); // Gives: Call to a member function get() on array. For obvious reasons
A dirty hack like Matei stated: Looping through the array and removing the KVP where the key is numeric. Which works, but I think the Laravel/Lumen framework offers cleaner solutions, which I am not able to find.

In config/database.php you can change 'fetch' => PDO::FETCH_CLASS, to 'fetch' => PDO::FETCH_ASSOC,
or
You can use array_reduce and array_filter like:
$result = json_decode(DB::select($query), true);
$result = array_reduce($result, function ($result, $item) {
$result[] = array_filter($result, function ($key) {
return !is_numeric($key);
}, ARRAY_FILTER_USE_KEY)
return $result;
}, array());
return json_encode($result);
NOTE: If the DB stmt is returning an array, rather than a json encoded string, then you must remove the json_decode and json_encode functions calls.

Related

Find the value of a key in an unknown multilevel array in PHP

I have a use defined json string inside a database.
The JSON string has lots of levels. I know my user will define a kay called "basevalue" and place it somewhere in the json.
The problem is, I don't know ahead of time where in the JSON it will be placed, and every use is likely to place is in different places in the array, perhaps at different levels.
This is an example of the JSON data being saved by the user:
{
"name": "",
"type": "layout",
"children": [
{
"name": "",
"type": "section",
"children": [
{
"name": "",
"type": "row",
"children": [
{
"name": "",
"type": "column",
"props": {
},
"children": []
},
{
"type": "column",
"children": [
{
"type": "itemdata",
"props": {
**"basevalue": "100",**
},
"children": []
}
]
}
]
}
]
}
I'm converting this data to an array using json_decode:
$json = json_decode($json, true);
No I need to search through the array, and find the key of 'basevalue' and then get whatever value the user has input, in the case above that would be '100'.
So to the issue is, I have no idea what 'node' the 'basevalue' key will be. It could be 40 deep, it could be in the first 'children' node.
This is up to the user.
So how do I take any version of the JSON string about and return the '100'?
Many thanks.
You can recursively iterate over the data and get the value of the key basevalue. To make this search faster, we can adopt an early exit approach similar to breadth first search. By this, we call add all values who are arrays in a queue and continue our search for the key basevalue and later on deal with pending queue. This would be faster than basic recursion because a lot of times it's possible that key was on the same level but we searched all the way down on all other trees which proved out to be trivial.
Snippet:
function getBaseValue($arr,$search_key){
$pending_calls = [];
foreach($arr as $key => $value){
if(is_array($value)){
$pending_calls[] = $value; // queue them for later judgement
}else if($search_key === $key){
return $value;
}
}
foreach($pending_calls as $call){
$returned_val = getBaseValue($call,$search_key);
if($returned_val !== false) return $returned_val;
}
return false;
}
echo getBaseValue($arr,'basevalue');
Demo: https://3v4l.org/gdLK1

I want a more consolidate json format

I am getting json array after getting applying query logic.
[
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-20"
},
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "CRP",
"booking_date": "2018-05-20"
},
{
"id": "4",
"diag_name": "Seepz Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-21"
}
]
But i want a more justified json array written below.
[
{
"diag_name": "LT Diagnostics",
"test_name": [
{
"id": "3",
"name" : "Alk PO4"
},
{
"id": "3",
"name" : "CRP"
}
],
"booking_date": "2018-05-20"
},
{
"diag_name": "Seepz Diagnostics",
"test_name": [
{
"id": "4",
"name" : "Alk PO4"
}
],
"booking_date": "2018-05-21"
},
]
I am not getting it,How to do in php. I want a more consolidate json format.
Have you tried changing your SQL query to group by diag_name and booking_date? That would be the first step I’d employ to get the outer data.
Formatting the data in the nested manner you’re after could be a function of whatever record serializer you’re using — does it support nested JSON as a return type, or only flat JSON as your example return value shows?
If the record set -> JSON serializer only ever returns flat data, the comments above are correct that you will have to write your own formatter to change the shape of the JSON yourself...
The accepted answer of this other question may be of help:
Create multi-level JSON with PHP and MySQL
I'm not a PHP guy but this is a typical scenario to use functional programming by means of the monad Map.
Looking online I've found this article that could help you.
Changing datasource output is not always (seldom indeed) a viable option.
Enjoy coding

"Nested" array within db response using Codeigniter

I am trying to create a "nested" array within an object that I am returning from a database.
I can have more than one footnote per "thing".
This is what I am currently getting back:
JSON
{
"data": [{
"id": "123",
"type": "foo",
"color": "bar",
"footnote_id": "1",
"footnote_text": " Footnote one"
}]
}
Here is the result I'm trying to generate:
JSON
{
"data": [{
"id": "123",
"type": "foo",
"color": "bar",
"footnotes": [{
"footnote_id": "1",
"footnote_text": " Footnote one"
},
{
"footnote_id": "2",
"footnote_text": "Footnote two"
}]
}]
}
I have a footnotes table that has all kinds of footnotes (footnote_id and such).
I have a type table that has all kinds of things in it (type_id and such).
I also have a type_footnotes table that only has two columns: type_id and footnote_id
I'm not sure how to create the footnotes property of the response object - then display the results within that array.
Thank you for your time!
EDIT
Here is the query - I thought I had posted this as well. My apologies.
PHP
public function get_thing($type_id) {
$this->db->select('type.type_id, type.type, type.type_color');
$this->db->join('footnotes', 'footnotes.footnote_id, footnotes.footnote_text');
$this->db->join('type_footnotes, type_footnotes.type_id = type.type_id');
$query = $this->db->get_where('type', array('type.type_id' => $type_id), 1);
if ($query->num_rows() > 0) {
return $query->result();
}
}
Remove the limit, and post here what do you get as result :
$query = $this->db->get_where('type', array('type.type_id' => $type_id));

Sort data from mongodb by decending order

I am trying to output users chat history and then put it into a JSON object I want the messages to come out in descending order but when I try $cursor->sort() is throwing Call to a member function sort() on a non-object
$cursor = $collection->findOne(array('chatbetween' => $channel_name));
$cursor->sort(array('messages' => -1));
$messages = array();
for($i=0; $i<count($cursor['messages']); $i++){
$object = array('message'=>$cursor['messages'][$i]['message'],
'time'=>date('Y-m-d\TH:i:s\Z', $cursor['messages'][$i]['time']->sec),
'user'=>$cursor['messages'][$i]['user']);
$messages[] = $object;
}
echo json_encode($messages);
Here is what a collection looks like.
"_id": ObjectId("4f3c19e37edae1723d000000"),
"chatbetween": "private-4f3bb96d7edae1850b0000004f3c0d2d7edae1e935010000",
"messages"▼: {
"0": {
"user": "4f3c0d2d7edae1e935010000",
"time": ISODate("2012-02-15T20: 47: 30.175Z"),
"message": "message1"
},
"1": {
"user": "4f3bb96d7edae1850b000000",
"time": ISODate("2012-02-15T20: 47: 37.79Z"),
"message": "message2"
},
"2": {
"user": "4f3c0d2d7edae1e935010000",
"time": ISODate("2012-02-15T20: 47: 43.295Z"),
"message": "message3"
}
}
Your problem is you're trying to sort sub-documents, whereas the .sort() function is for sorting documents.
So, each object in the collection is a document--in this case, each chat is a document. You can sort your chats with .sort(), but you have subdocuments called messages within your documents (sub-documents), and Mongo doesn't sort those for you.
See some answers to a similar question here:
Sort Sub Documents in MongoDB

Pull unique key names from json data, like SQL select distinct from**********

I have the following json data:
{
"data": [
{
"name": "The Frugalicious Chef",
"category": "Chef",
"id": "186397894735983",
"created_time": "2011-03-07T16:10:35+0000"
},
{
"name": "Siuslaw Broadband",
"category": "Telecommunication",
"id": "190373850988171",
"created_time": "2011-03-06T20:21:42+0000"
},
{
"name": "Paul",
"category": "Movie",
"id": "129989595478",
"created_time": "2011-03-04T19:55:18+0000"
},
{
"name": "Mark Zuckerberg",
"category": "Public figure",
"id": "68310606562",
"created_time": "2011-02-16T09:50:35+0000"
},
The idea here is that I want to take this data and use parts of it. I want to create a list of the "category's" that are in the data. The problem is that there is and will be multiple items with the same category. So my list will have duplicates that I do not want. The following is how I am getting the data and converting it for use:
$jsonurl = "https://xxxxxxxxxx.com/".$fd_ID. "/info?access_token=".$session['access_token'];
$likesjson = file_get_contents($jsonurl,0,null,null);
$likesArray=json_decode($likesjson);
I then use a foreach to access the data.
foreach($friendLikesArray->data as $l)
{
etc......
}
So I guess muy question is I want to take the $likesArray and pull out all the unique Data->Category->names. Also will want to do sorting, and other things but I will get to that when the time comes.
Thanks for the help in advance.
Neil
The data structure you would want to use is a set, that only allows unique entries.
A simple implementation using PHP arrays is to use the keys.
e.g.
$categories = array();
foreach($friendLikesArray->data as $l)
{
$categories[$l->category] = true;
}
$categories = array_keys($categories);
This way if the category has already been added, then you are not adding anything new to the array.
If the keys are not important to you then you can use the line:
$categories[$l->category] = $l->category
But this means your array won't have 0,1,2...n for keys.

Categories