MySQL PDO fetchAll as array with format - php

I have this PDO code
function getAllUserTicketHistoryJson($rid){
global $conn;
$stmt = $conn->prepare("SELECT user_id, total_ticket FROM lottery_user WHERE round_id = :rou");
$stmt->bindParam(':rou', $rid);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$res = $stmt->fetchAll();
return $res;
}
and show the data in my index php file like this one
$getAllUserTicketHistoryJson = getAllUserTicketHistoryJson($getRound['id']);
And call all the data to this one
foreach($getAllUserTicketHistoryJson as $key => $value){
$array=$value;
}
when I try to var_export($value); the data show like this
array ( 'user_id' => '1', 'total_ticket' => '1', )array ( 'user_id' => '2', 'total_ticket' => '50', )array ( 'user_id' => '3', 'total_ticket' => '10', )array ( 'user_id' => '4', 'total_ticket' => '5', )
My question is, can I get the data display in one array?
should be like this
array("1" => 1, '2' => 50, '3' => 10, '4' => 5)
how to get the data become inside one array only?

Found the answer, we need a custom format in foreach.
so the code will be like this
$data = array();
foreach($getAllUserTicketHistoryJson as $value){
$data[$value['user_id']] = number_format((float)($value['total_ticket'] / $getAllTicketRound * 100), 2, '.', '');
}

Related

Codeigniter 4: Merge arrays then use InsertBatch to insert data in MySQL

I'm trying to insert multiple rows into MySQL using the 'InsertBatch' function. However, I am unable to make it work. I'm new to this, and I'm not sure if I'm doing it correctly.
I'm using input and select fields with $is data and a table with $tmp data. I used foreach and for statements to get the $tmp_data on the table. An array push() was also used to merge the data into an array.
public function Add_Fees_Matrix() {
$fm_model = new Mod_Fees_Matrix();
$data = [];
//input and select type
$is_data = [
'fm_code' => $this->request->getPost('fm_code'),
'sy_id' => $this->request->getPost('sy_id'),
'dept_id' => $this->request->getPost('dept'),
'gl_id' => $this->request->getPost('gl_id'),
'ppl_id' => $this->request->getPost('ppl_mode')
];
//table
$tmp_data = [
'fcp_description' => $_POST['fcp_description'],
'fmf_amount' => $_POST['fmf_amount']
];
foreach ($tmp_data as $k => $v) {
for($i = 0; $i < count($v);$i++) {
array_push($data, $is_data);
$data[$i][$k] = $v[$i];
}
}
echo "<pre>";
var_export($data);
$fm_model->insertBatch($data);
}
In my output, it generates four arrays. However, only the first two arrays are considered necessary. I think the problem is caused by the array push() function.
Here's the output of var_export():
array (
0 =>
array (
'fm_code' => 'FM-1741195162687292',
'sy_id' => '2',
'dept_id' => '1',
'gl_id' => '2',
'ppl_id' => '1',
'fcp_description' => 'INSTITUTIONAL DEVELOPMENT FEE',
'fmf_amount' => '123',
),
1 =>
array (
'fm_code' => 'FM-1741195162687292',
'sy_id' => '2',
'dept_id' => '1',
'gl_id' => '2',
'ppl_id' => '1',
'fcp_description' => 'MATRICULATION',
'fmf_amount' => '1230',
),
2 =>
array (
'fm_code' => 'FM-1741195162687292',
'sy_id' => '2',
'dept_id' => '1',
'gl_id' => '2',
'ppl_id' => '1',
),
3 =>
array (
'fm_code' => 'FM-1741195162687292',
'sy_id' => '2',
'dept_id' => '1',
'gl_id' => '2',
'ppl_id' => '1',
),
)
Upon clicking a button, can someone help me to insert the data on my database?
This seems to work in my problem.
public function Add_Fees_Matrix() {
$fm_model = new Mod_Fees_Matrix();
$data = [];
$tmp_data = [
'fcp_description' => $this->request->getPost('fcp_description'),
'fcp_amount' => $this->request->getPost('fmf_amount')
];
foreach ($tmp_data as $k => $v) {
for($i = 0; $i < count($v);$i++) {
$data[$i]['fm_code'] = $this->request->getPost('fm_code');
$data[$i]['sy_id'] = $this->request->getPost('sy_id');
$data[$i]['dept_id'] = $this->request->getPost('dept');
$data[$i]['gl_id'] = $this->request->getPost('gl_id');
$data[$i]['ppl_id'] = $this->request->getPost('ppl_mode');
$data[$i][$k] = $v[$i];
}
}
$fm_model->insertBatch($data);
echo "<pre>";
var_export($data);
}

convert normal array in nested array with php

I have a hierarchical database table like below
ID Name Subcategory ParentID
1 ABC 0
2 DEF QFE 0
3 QFE XYZ 2
4 XYZ MNJ 3
From Thant I have got PHP array like below
$array_name = array(
array('ID' => '1', 'Name' => 'ABC', 'Subcategory' => '', 'ParentID' => '0'),
array('ID' => '2', 'Name' => 'DEF', 'Subcategory' => 'QFE', 'ParentID' => '0'),
array('ID' => '3', 'Name' => 'QFE', 'Subcategory' => 'XYZ', 'ParentID' => '2'),
array('ID' => '4', 'Name' => 'XYZ', 'Subcategory' => 'MNJ', 'ParentID' => '3')
);
but I want array like below
$array_name = array(
array('ID' => '1', 'Name' => 'ABC', 'Subcategory' => '', 'ParentID' => '0'),
array('ID' => '2', 'Name' => 'DEF', 'Subcategory' => array('ID' => '3', 'Name' => 'QFE', 'Subcategory' => array('ID' => '4', 'Name' => 'XYZ', 'Subcategory' => 'MNJ', 'ParentID' => '3'), 'ParentID' => '2'), 'ParentID' => '0'),
);
I want a function which checks is that row have some Subcategory or not and if a row has Subcategory then get that subcategory row as an array and make one array with all category and Subcategory
for that, I have tried to make a function which is given below
function find_subcategory($ID,$con){
$table_name ="SELECT * FROM `table_name` WHERE `parent_id` = '$ID'";
$table_name_result = mysqli_query($con,$table_name);
$category_array = array();
if(mysqli_num_rows($table_name_result)) {
while($row = mysqli_fetch_assoc($table_name_result)) {
$Subcategory= $row['Subcategory'];
$ID = $row['ID'];
if ($Subcategory== '') {
$find_subcategory = find_subcategory($ID,$con);
$row['Subcategory'] = $find_subcategory;
$category_array[] = $row;
}else{
$category_array[] = $row;
}
}
}
return json_encode(array('tbl_category'=>$category_array));
}
but this function is not working to get all the subcategories of one category.
can anybody help me with this
Rather than create a recursive routine, which executes the SQL for each level, this instead reads all of the categories in and them assembles them into the hierarchy.
Note that it reads them in reverse order so that when it assembles them, each subcategory is always read before the parent (More details in code comments)...
$table_name ="SELECT * FROM `category` ORDER BY parent_id DESC, id desc";
$table_name_result = mysqli_query($con,$table_name);
$categories = mysqli_fetch_all($table_name_result, MYSQLI_ASSOC);
$output= [];
foreach ( $categories as $category) {
// If there is a parent for this item
if ( !empty ($category['parent_id']) ) {
// Set basic details
$output[$category['parent_id']]['Subcategory'][$category['id']] = $category;
// If there is already some data (subcategories)
if ( isset($output[$category['id']]) ){
// Copy subcategories
$output[$category['parent_id']]['Subcategory'][$category['id']] +=
$output[$category['id']];
// Remove old node
unset ( $output[$category['id']] );
}
}
else {
// Add in category data (allow for existing data to be added
$output[$category['id']] = $category + ($output[$category['id']]??[]);
}
}
I successfully implemented and tested a recursive routine to solve this. However, for performance reasons I had to decouple the access to the database from the recursive call.
First, you fetch your query into an array as you already have and then recursively rearrange the elements so that the keys are nested in the proper order.
Pretty much of the explanations I'd like to put here are put as comments in the code.
$array_name = array(
array('ID' => '1', 'Name' => 'ABC', 'Subcategory' => '', 'ParentID' => '0'),
array('ID' => '2', 'Name' => 'DEF', 'Subcategory' => 'QFE', 'ParentID' => '0'),
array('ID' => '3', 'Name' => 'QFE', 'Subcategory' => 'XYZ', 'ParentID' => '2'),
array('ID' => '4', 'Name' => 'XYZ', 'Subcategory' => 'MNJ', 'ParentID' => '3'),
array('ID' => '5', 'Name' => 'XYY', 'Subcategory' => 'MNJ', 'ParentID' => '1')
);
// recreate nested array
function get_nested_array($arr) {
$new_arr = array(); // new array to collect each top level element with nesting
foreach ($arr as $key => $value) {
// only top level elements would appear here as they would not be nested
if($value['ParentID'] == '0') {
array_push($new_arr, get_nested_item($value, $arr));
}
}
return $new_arr;
}
// recursive function to perform nesting on each element
function get_nested_item($hay, $stack) {
foreach ($stack as $key => $value) {
if ($hay['ID'] == $value['ParentID']) {
$index = get_key($hay, $stack);
// reduce $stack size by removing the HAY from the STACK
// recursion terminates when $stack size is 0
$stack = $index >= 0 ? array_splice($stack, $index) : [];
// update subcategory of the found nesting
$hay['Subcategory'] = get_nested_item($value, $stack);
}
}
return $hay;
}
// get the position of $hay in a $stack using the ID
function get_key($hay, $stack) {
foreach ($stack as $key => $value) {
if($hay['ID'] == $value['ID']) return $key;
}
return -1;
}
// print array so that it understandable
function print_array($arr) {
foreach ($arr as $key => $value) {
print_r($value);
echo "<br>";
}
}
// Test case
// print array before nesting
print_array($array_name);
echo"<br>";
// print array after nesting
$new_array = get_nested_array($array_name);
print_array($new_array);

Convert a 2D array to JSON in PHP

My goal is to make a single database hit to generate a JSON array of objects with attributes that could be also be an array of objects, which could also have attributes that array of objects etc of an arbitrary (but known) depth.
I get a 2D array from my database using a PDO object.
$stmt = $this->pdo->prepare($sql);
$stmt->execute($args);
$TwoDimArray = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $TwoDimArray;
So in my example, I have a Quiz, that can have questions, that can have answers. So a depth of 3. So assuming I have a 2D Array such as the table below, how would I make this JSON array using that data. (Note: other data has been removed for clarity sake, but questions and answers could have other attributes.)
Edit: This is my attempt. It is horribly inefficient and not very abstract for the general case but this code will achieve the right answer for small data sets.
$data = ($database -> query($sql,$args)); // the result is $TwoDimArray
$quizes = array();
$quiz_id_list = array();
foreach($data as $quizkey => $quizvalue){
if(!in_array($quizvalue["quiz_id"], $quiz_id_list)) {
array_push($quiz_id_list, $quizvalue["quiz_id"]);
$question_id_list = array();
$questions = array();
foreach ($data as $questionskey => $questionsvalue) {
if ($quizvalue["quiz_id"] == $questionsvalue["quiz_id"] && !in_array($questionsvalue["question_id"], $question_id_list)) {
$answers = array();
array_push($question_id_list, $questionsvalue["question_id"]);
foreach ($data as $answerskey => $answersvalue) {
$myanswer = array();
if ($questionsvalue["question_id"] == $answersvalue["question_id"]) {
$myanswer["answer_id"] = $answersvalue["answer_id"];
array_push($answers, $myanswer);
}
}
$myquestion = array();
$myquestion["question_id"] = $questionsvalue["question_id"];
$myquestion["answers"] = $answers;
array_push($questions, $myquestion);
}
}
$myquiz = array();
$myquiz["quiz_id"] = $quizvalue["quiz_id"];
$myquiz["questions"] = $questions;
array_push($quizes, $myquiz);
}
}
return json_encode($quizes);
The contents of $data looks like this:
array (
0 =>array('quiz_id' => '1', 'question_id' => '1', 'answer_id' => '1',),
1 =>array('quiz_id' => '1', 'question_id' => '1', 'answer_id' => '2',),
...
5 =>array('quiz_id' => '1', 'question_id' => '2', 'answer_id' => '6',),
6 =>array('quiz_id' => '1', 'question_id' => '2', 'answer_id' => '7',),
...
22 =>array('quiz_id' => '2', 'question_id' => '6', 'answer_id' => '23',),
23 =>array('quiz_id' => '2', 'question_id' => '6', 'answer_id' => '24',),
)
The result should return a json object that looks like this:
[
{
"quiz_id": 1,
"questions": [
{"question_id":1, "answers": [{"answer_id":1}, {"answer_id":2}, {"answer_id":3},{"answer_id":4}]},
{"question_id":2, "answers": [{"answer_id":5}, {"answer_id":6}, {"answer_id":7},{"answer_id":8}]},
{"question_id":3, "answers": [{"answer_id":9}, {"answer_id":10}, {"answer_id":11},{"answer_id":12}]}
]
},
{
"quiz_id": 2,
"questions": [
{"question_id":4, "answers": [{"answer_id":13}, {"answer_id":14}, {"answer_id":15},{"answer_id":16}]},
{"question_id":5, "answers": [{"answer_id":17}, {"answer_id":18}, {"answer_id":19},{"answer_id":20}]},
{"question_id":6, "answers": [{"answer_id":21}, {"answer_id":22}, {"answer_id":23},{"answer_id":24}]}
]
}
]
You say this is the contents of $TwoDimArray There is not much that can be done with it. I suspect there is something missing yet.
array ( 'quiz_id' => '1', 'question_id' => '1', 'answer_id' => '1', ),
array ( 'quiz_id' => '1', 'question_id' => '1', 'answer_id' => '2', ),
array ( 'quiz_id' => '1', 'question_id' => '1', 'answer_id' => '3', ),
This will get rid of your "redundant data":
foreach($TwoDimArray as $value){
$quiz[$value['quiz_id']][$value['question_id']][$value['question_id']] = 1;
}

Cakephp sort by first item in array

I have an array that looks like the following:
Data = array(
'Offer' => array(),
'Country' = array('Name' => Array())
)
Now if i want to sort on the value of the first item of the Name array how would i go around that?
Ive tried this so far:
$dataArray = $originalData['data'];
$dataArray = Set::sort($dataArray, '{n}.Country.Name', $direction);
However this did not work
Note im using CakePHP set::Sort is a part of Cakephp
Okay seems i wasnt clear enough so here is a more detailed explaination of my problem:
So ive created my own datasource in cake that collects data from an API.
The API returns data in a way that looks like this:
data = array(
'Offer' => array('id' => 2, 'name' = 'ExampleName'),
'Stat' => array('Stat1' = 1, 'Stat2' = 2),
'Country => array('Name' => array('name1','name2')
);
Now in order to make the user able to sort these data i have to make sure that i display correctly.
This works fine when there is only one value i.e:
$dataArray = $originalData['data'];
$dataArray = Set::sort($dataArray, '{n}.Stat.Stat1', 'ASC);
$originalData['data'] = $dataArray;
However country is an array so in order to "copy" the code above i need to use the first item of the Country['Name'] array.
to do something like this:
$dataArray = $originalData['data'];
$dataArray = Set::sort($dataArray, '{n}.Country.Name', $direction);
$originalData['data'] = $dataArray;
However the above code is failing ...
created test data:
$dataArray = array();
$data = array(
'Offer' => array('id' => 2, 'name' => 'ExampleName'),
'Stat' => array('Stat1' => 1, 'Stat2' => 2),
'Country' => array('Name' => array('z','name2'))
);
array_push($dataArray,$data);
$data = array(
'Offer' => array('id' => 2, 'name' => 'ExampleName'),
'Stat' => array('Stat1' => 1, 'Stat2' => 3),
'Country' => array('Name' => array('a','name2'))
);
array_push($dataArray,$data);
print_r(Set::sort($dataArray,'{n}.Country.Name','asc'));
Link with output array:https://gist.github.com/anonymous/6462971

Processing data from query

I'm writing a 'get' function in a model class in codeigniter, but I need to process some of the data as it's returned, ideally without a whole bunch of overhead.
function get_answers($p)
{
$result = $this->db->get_where('answer', array('a_upid_fk' => $p))->result();
// foreach ($result->answer as $ans) {
// $result->answers = explode( '|', $ans, -1 );
// }
return $result;
}
The results look like this:
array (
0 =>
stdClass::__set_state(array(
'aid' => '742',
'a_upid_fk' => '231',
'answer' => '4555|||',
'a_qid_fk' => '70',
'created' => '2012-04-20 15:35:38',
'last_modified' => '2012-04-20 15:36:11',
'revision' => '1',
)),
1 =>
stdClass::__set_state(array(
'aid' => '743',
'a_upid_fk' => '231',
'answer' => NULL,
'a_qid_fk' => '71',
'created' => '2012-04-20 15:35:38',
'last_modified' => '2012-04-20 15:35:38',
'revision' => '1',
)) ...
the problem is the answer is stored as a pipe delimited list of answers, but I want the function to return it as an exploded array instead. I'm not sure of the syntax and how to create and replace or append the array to the array of objects I've pasted above.
You can see some code I've been trying commented out.
Ideally instead of 'answer' => '4555|||',
I would like to have
'answer' => array (
0 => '4555',
1=> '',
2=> '')
I have no problem making the array using explode but I'm not sure how to modify the original codeigniter active-record result.
Loop thru your sub-arrays:
$answer_array = explode('|', $answer);
foreach ($aswer_array as $instance)
{
$result[] = $instance;
}
Define __set_state()), call it using - $subarray = $result[0][$object->answer].

Categories