Result set of laravel data in proper format - php

i am using laravel to make an API that queries a database and show a simple output. Now my query goes like this:
$name = new TableName() ; //An object which is storing tablename
$result=DB::table($name->getMyTableName()) // Getting the tablename
->select()
->where('id','=',1)->orWhere('id','=',2)
->get();
Now this will fetch two records with id 1 and 2 and when I pass them through my controller, the json out put comes like this:
[
{
"id": "1",
"question": "This is",
"question_main": "sample1",
"option_1": "opt_1",
"option_2": "opt_1",
"option_3": "opt_1",
"option_4": "opt_1",
},
{
"id": "2",
"question": "This is",
"question_main": "sample2",
"option_1": "opt_1",
"option_2": "opt_2",
"option_3": "opt_3",
"option_4": "opt_4",
}
]
Now what I want is instead of option, i have something like this:
option :
{
1=>"opt_1",
2=>"opt_2",
3=>"opt_3",
4=>"opt_4",
}
Now what i tried is this:
foreach ($result as $results)
{
$final_result= array_add($final_result, 'id', $results->id);
$final_result= array_add($final_result, 'question', $results->question);
$final_result= array_add($final_result, 'question_main', $results->question_main);
$final_result= array_add($final_result, 'options', array(
[
1 => $results->option_1,
2 => $results->option_2,
3 => $results->option_3,
4 => $results->option_4,
]
));
}
return json_encode($final_result,JSON_PRETTY_PRINT);
This pretty much solves the problem however as you might have figured out key-value pair can have unique key so it will just store id=2 (the latter). I am pretty much confused on what to follow. I tried Multi dimensional array but i think i couldn't get the concept right on that.Any suggestions, thanks in advance

You can do the following using the key in your foreach:
$final_result = [];
foreach ($result as $key => $results)
{
$final_result[$key] = [
'id' => $results->id,
'question' => $results->question,
'question_main' => $results->question_main,
'options' => [
1 => $results->option_1,
2 => $results->option_2,
3 => $results->option_3,
4 => $results->option_4
]
];
}
return json_encode($final_result,JSON_PRETTY_PRINT);

This would do the desired.
$arrayToBePrinted = [];
foreach ($result as $results)
{
$final_result= array_add($final_result, 'id', $results->id);
$final_result= array_add($final_result, 'question', $results->question);
$final_result= array_add($final_result, 'question_main', $results->question_main);
$final_result= array_add($final_result, 'options', array(
[
1 => $results->option_1,
2 => $results->option_2,
3 => $results->option_3,
4 => $results->option_4,
]
));
$arrayToBePrinted[] = $final_result;
}
return json_encode($arrayToBePrinted,JSON_PRETTY_PRINT);

Related

How do i merge these arrays into one [duplicate]

This question already has answers here:
Merge two arrays into one associative array
(2 answers)
Closed 7 months ago.
I want to change the following php array
"extra_charge_item" => [
0 => "Massage",
1 => "Pool table",
2 => "Laundry"
],
"extra_charge_description" => [
0 => "Paid",
1 => "Paid",
2 => "We wash everything"
],
"extra_charge_price" => [
0 => "200",
1 => "100",
2 => "1000"
],
I haven't been able to solve for a whole 2hrs
This is the expected output
"new_data" => [
0 => [
"Maasage", "Paid", "200"
],
1 => [
"Pool table", "Paid", "100"
],
2 => [
"Laundry", "we wash everything", "1000"
]
]
Rather than doing all the work for you, here's some pointers on one way to approach this:
If you are happy to assume that all three sub-arrays have the same number of items, you can use array_keys to get those keys from whichever you want.
Once you have those keys, you can use a foreach loop to look at each in turn.
For each key, use square bracket syntax to pluck the three items you need.
Use [$foo, $bar, $baz] or array($foo, $bar, $baz) to create a new array.
Assign that array to your final output array, using the key from your foreach loop.
Just use foreach with key => value
$data = [
"extra_charge_item" => [
0 => "Massage",
1 => "Pool table",
2 => "Laundry"
],
"extra_charge_description" => [
0 => "Paid",
1 => "Paid",
2 => "We wash everything"
],
"extra_charge_price" => [
0 => "200",
1 => "100",
2 => "1000"
],
];
$newData = [];
foreach ($data as $value) {
foreach ($value as $k => $v) {
$newData[$k][] = $v;
}
}
var_dump($newData);
I found an answer. Seems someone else had the same problem
Merge two arrays into one associative array
Here's the solution for my case;
//These are arrays passed from front end in the name attribute e.g extra_charge_item[] e.t.c
$extra_charge_item_array = $request->input('extra_charge_item');
$extra_charge_description_array = $request->input('extra_charge_description');
$extra_charge_price_array = $request->input('extra_charge_price');
$new_extra_charges_data = array_map(
function ($item, $description, $price) {
return [
'item' => $item,
'description' => $description,
'price'=> $price
];
}, $extra_charge_item_array, $extra_charge_description_array, $extra_charge_price_array);
//save the data
foreach ($new_extra_charges_data as $extra_charge) {
Charge::create([
'item' => $extra_charge['item'],
'description' => $extra_charge['description'],
'price' => $extra_charge['price']
]);
}

How can I build an object/array?

I am rather new to PHP so I don't know how to work with these datasets. I make a MySQL select and get back an object like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": "7.70"
},
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 3,
"dailyworkhourssum": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
I want to iterate through this and in the end it should look like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid1": true,
"categorid3": true,
"dailyworkhourssum1": "7.70",
"dailyworkhourssum3": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
What this does is that it merges tow fields together (if they have the same bookingdate )into one so that I can display it in a table without reoccurring dates.
My problem:
I don't know what this type of data is called.
I don't know how to create something like this.
I can add fields to this type of data with $data->newField = example so I think that this is an object.
In JS it's called an object, but in PHP you will use an associative array instead.
In your case, I think, you have an array of associative arrays. It looks like this:
$books = [
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 1,
"dailyworkhourssum" => "7.70"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 3,
"dailyworkhourssum" => "1.2"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-05",
"categoryid" => 3,
"dailyworkhourssum" => "7.70"
]
];
If you wanna merge an arrays with the same "bookingdate" then I recommend you to loop through this array and add its elements to another associative array with bookingdates as keys, and check, in case if there is such key already, then merge the arrays, like this:
$merged = [];
foreach ($books as $book) {
$date = $book['bookingdate'];
if (isset($merged[$date])) {
$merged[$date] = $merged[$date] + $book;
} else {
$merged[$date] = $book;
}
}
I think that it is not a valid code (no time, sorry), but I hope, you cautch the idea.
If you want a 'list' instead of an associative array, than you can do this:
$mergedList = array_values($merged);
Thus you will rid of string keys.
If I understood correctly, you obtain a table with 4 columns an a variable number of rows and you want to transform it to a table with a variable number of columns. For that, using a data structure where every item is different from the previous one can make everything harder than it needs. I'd suggest you use a fixed structure:
// I'm assuming you have a PHP array as starting point
$input = [
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 1,
'dailyworkhourssum' => '7.70',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 3,
'dailyworkhourssum' => '1.2',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-05',
'categoryid' => 3,
'dailyworkhourssum' => '7.70',
],
];
$output = [];
foreach ($input as $data) {
// We'll group by booking date
if (!isset($output[$data['bookingdate']])) {
$output[$data['bookingdate']] = [
'membername' => $data['membername'],
'bookingdate' => $data['bookingdate'],
'categoryid' => $data['categoryid'],
'dailyworkhourssum' => [],
];
}
// A single date may have several daily work hours
$output[$data['bookingdate']]['dailyworkhourssum'][] = $data['dailyworkhourssum'];
}
// We discard array keys (we only needed them to group)
echo json_encode(array_values($output));
[{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": ["7.70", "1.2"]
}, {
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": ["7.70"]
}]
Wherever you consume this JSON you just need to loop the dailyworkhourssum array. You may also want to loop the entire structure before printing the table and keep a counter in order to determine the maximum number of columns so you can draw empty cells where needed (tables are rectangular).

How to select a field of a contained association as a field of the main entity?

I have Cakephp 3 in a project and I'm doing api rest to get a JSON to get data in mobile devices.
I have two tables in associated with a foreign key like this:
MySql tables
----------------------
Table Tickets:
|id|code|price_id|
Table Prices
|id|price|
----------------------
In TicketsTable CakePHP:
$this->belongsTo('Prices', [
'foreignKey' => 'price_id',
'joinType' => 'INNER'
]);
In controller when I make REST api:
$this->loadModel('Tickets');
$entradas = $this-> Tickets->find('all')
->contain('Prices')
->select(['Tickets.code','Prices.price'])
->limit('200')
->toArray();
Then this array, parsed to JSON return this:
"result":{
"tickets":[
{
"code":"08998112773",
"prices":{
"prices.price":1
}
},
{
"code":"07615265880",
"prices.prices":{ .........
And I want to return this JSON:
"result":{
"tickets":[
{
"code":"08998112773",
"price":1
},
{
"code":"07615265880",
"price":1 .........
That is, that prices do not insert into a new array and that the name of the table does not appear in the field name.
Thanks a lot!!!!
You could use use Cake\Collection\Collection::map() to create a new array:
$tickets = [
'result' => [
'tickets' => [
[
'code' => '123',
'prices' => [
'prices.price' => '2'
]
],
[
'code' => '312423',
'prices' => [
'prices.price' => '4'
]
]
]
]
];
$collection = new Collection($tickets['result']['tickets']);
$new = $collection->map(function ($value, $key) {
return [
'code' => $value['code'],
'price' => $value['prices']['prices.price']
];
});
$result = $new->toArray();
debug(json_encode(['result' => ['tickets' => $new]], JSON_PRETTY_PRINT));
die;
The output is:
{
"result": {
"tickets": [
{
"code": "123",
"price": "2"
},
{
"code": "312423",
"price": "4"
}
]
}
}

Laravel php get last element in multidimensional array

I have the following json file with products details:
"products": [
{
"sku": 123,
"name": "iphone 7",
"categoryPath": [
{
"id": "abcat0800000",
"name": "Cell Phones"
},
{
"id": "pcmcat209400050001",
"name": "All Cell Phones with Plans"
}
],
}
]
I would like only to store the last value (ID and NAME) of the categoryPath Array:
"id": "pcmcat209400050001",
"name": "All Cell Phones with Plans"
My current code takes the json file, decode the json and insert in products table the information.
$json = File::get("/json/cell-0.json");
$data = json_decode($json);
$array1 = (array)$data;
//table products
foreach ($array1['products'] as $obj) {
DB::table('products')->insert(array(
'productSku' => ((isset($obj->sku) ? $obj->sku : 1)),
'productName' => ((isset($obj->name) ? $obj->name : null)),
'categoryId' => end($obj->categoryPath->id),
'categoryName' => end($obj->categoryPath->name)
));
Taking into consideration that array->categoryPath have multiple fields I would like to use a function (eg: end()) in order to take id and name only of the last values.
Using end($obj->categoryPath->id) I receive the following error ->
Attempt to modify property of non-object
Is this the best way to retrieve the last value of a multidimensional array?
You could use end() probably but your accessors would have to be outside the end() call (untested):
foreach ($array1['products'] as $obj) {
DB::table('products')->insert(array(
'productSku' => ((isset($obj->sku) ? $obj->sku : 1)),
'productName' => ((isset($obj->name) ? $obj->name : null)),
'categoryId' => end($obj->categoryPath)->id,
'categoryName' => end($obj->categoryPath)->name
));
The way you're getting the last element is incorrect, here is the refactored code. I also eliminated the need to cast data as an array as well.
$json = File::get("/json/cell-0.json");
$data = json_decode($json, true);
//table products
foreach ($data['products'] as $product) {
$lastCategory = isset($product['categoryPath']) && $size = sizeof($product['categoryPath']) ? $product['categoryPath'][$size-1] : array('id' => null, 'name' => null);
DB::table('products')->insert(
array(
'productSku' => isset($product['sku']) ? $product['sku'] : 1,
'productName' => isset($product['name']) ? $product['name'] : null,
'categoryId' => lastCategory['id'],
'categoryName' => lastCategory['name']
)
);
}

How to create json string given below

I am android developer and new in PHP. I don't know PHP very well. I create
<?php
header('Content-Type: application/json; charset=utf-8');
$mysqli = new mysqli ('localhost', 'mabhi', '9993', 'general');
//PROBLEM LANGUAGE ?????
if (function_exists('mysql_set_charset')) {
mysqli_set_charset($mysqli, 'utf8');
} else {
mysqli_query($mysqli, "SET NAMES 'utf8'");
}
// Check if album id is posted as GET parameter
$myq = $mysqli->query('SELECT * FROM Ages');
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
}
echo json_encode($array, JSON_UNESCAPED_UNICODE);
?>
output:
{
"Questions": [
{
"Question": "sfsa sfd s sdf",
"Answer": "vvv",
"CorrectAnswer": null
},
{
"Question": "dsfgdsfgv dsf dfs",
"Answer": "vvvv vv",
"CorrectAnswer": null
}
]
}
But I would like json output in below format: Answer are displayed multiple times for each question. Please suggest me what changes in my code.
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
{
"Answer": "vvvvvvv"
},
{
"Answer": "vvv"
},
{
"Answer": "vv"
},
{
"Answer": "v"
}
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
{
"Answer": "Lee"
},
{
"Answer": "Wrangler"
},
{
"Answer": "Levi's"
},
{
"Answer": "Diesel"
}
]
}
]
}
As pointed by jereon, you are overwriting the value of Answer key. You need to create a separate array for the all the Answers together.
Change
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
to
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answers' => array((object)array('Answer' => $myr['option1']),
(object)array('Answer' => $myr['option2']),
(object)array('Answer' => $myr['option3']),
(object)array('Answer' => $myr['option4'])),
'CorrectAnswer' => $myr['CorrectAnswer'],
));
You should not assign multiple array elements with the same identifier ("Answer") as they would just overwrite each other. I would suggest you to use a non-associative array for the Answers so that your target JSON would look like this:
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
"vvvvvvv",
"vvv",
"vv",
"v"
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
"Lee",
"Wrangler",
"Levi's",
"Diesel"
]
}
]
}
Therefore you would use the following PHP code for the loop:
$array = array();
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'Answers' => array(
$myr['option1'],
$myr['option2'],
$myr['option3'],
$myr['option4'],
),
);
}
First thing you are doing wrong is you are overwriting the value of answer options so what will happen is when your 1st option will be overwritten by 2nd option, 2nd option with 3rd and 3rd option with 4th option. So you will have to create an array for answers and push every answer in that array and in the end assign this answer option array to answer. So your code should look like below
while ( $myr = $myq->fetch_assoc () ) {
$answers_array=new array();
$answer_option=new stdClass(); // Create a object to format in required format and use this object to store every option of answer
$answer_option->answer=$myr['option1'];
array_push($answers_array,$answer_option);
$answer_option->answer=$myr['option2'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option3'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option4'];
array_push($answers_array,$answer_option);
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'answers' => $answers_array;
);
}

Categories