Get recursive depth for every row - php

I have the following db table
82 is the parent of 84. 24 is the parent of 82 and 83. In php I have a method to fetch rows by uid.
public function fetchByUid($uid){
//code
}
This would retrieve the 7th and 6th value from the table. Now I want to fetch not only the rows where uid is equal but also the rows where the parent is the child of uid. E.g. 82 is a parent of 84 but also a child of 24.
So I came up with some recursion.
public function fetchByUidRec($uid, $data, $counter){
//set of rows by uid
$db_resultSet;
foreach($db_resultSet as $row){
$entry = array();
$entry['id'] = $row->id;
$entry['uid'] = $row->uid;
$entry['rid'] = $row->rid;
$entry['layer'] = $counter;
$data [] = $entry;
//now I want to do the same on the child
$data [] = fetchByUidRec($row->rid, $data, $counter = $counter + 1)
}
return $data;
}
public function getchByUid($uid){
$data = array();
$counter = 0;
return fetchByUidRec($uid, $data, $counter)
}
But that does not work at all :( I want to store the current recrusion depth in $data['layer']
Any ideas?

If I understood you correctly:
$rows = array
(
0 => array('id' => 8, 'uid' => 82, 'rid' => 84),
1 => array('id' => 7, 'uid' => 24, 'rid' => 82),
2 => array('id' => 6, 'uid' => 24, 'rid' => 83),
);
function fetchByUidRec($uid, $counter = 0)
{
global $rows;
// or in your case
// $rows = SELECT FROM table WHERE uid = $uid;
$data = array();
foreach ($rows as $row)
{
if ($row['uid'] == $uid)
{
$data[] = array_merge($row, array('layer' => $counter));
$data = array_merge($data, fetchByUidRec($row['rid'], $counter++));
}
}
return $data;
}
Example:
echo '<pre>';
print_r(fetchByUidRec(24));
echo '</pre>';
Output:
Array
(
[0] => Array
(
[id] => 7
[uid] => 24
[rid] => 82
[layer] => 0
)
[1] => Array
(
[id] => 8
[uid] => 82
[rid] => 84
[layer] => 0
)
[2] => Array
(
[id] => 6
[uid] => 24
[rid] => 83
[layer] => 1
)
)

Related

Batch Update with Dynamic IDs Codeigniter

I'm trying to batch update a table by an ID
My controller:
if(customCompute($this->data['student'])) {
$studentextendID = $this->data['student']->studentextendID;
$this->data['students'] = $this->studentextend_m->get_studentextend(array('studentextendID' => $studentextendID));
} else {
$this->data['students'] = [];
}
$post = $this->input->post();
for($i=0; $i < count($post['subject']); $i++) {
$studentExtendArray[] = array(
'studentextendID' => $studentextendID,
'studentID' => $studentID,
'subject' => $post['subject'][$i],
'subjectng' => $post['subjectng'][$i],
'subjectlg' => $post['subjectlg'][$i],
'subjectcre' => $post['subjectcre'][$i],
);
$this->db->update_batch('studentextend', $studentExtendArray, 'studentextendID');
}
My Model
function get_studentextend($array=NULL, $signal=FALSE) {
$query = parent::get($array, $signal);
return $query;
}
Array Output:
Array (
[0] => Array
(
[studentextendID] => 143
[studentID] => 97
[subject] =>
[subjectng] => 5235
[subjectlg] => 5231
[subjectcre] => 523155
)
[1] => Array
(
[studentextendID] => 143
[studentID] => 97
[subject] =>
[subjectng] => 2
[subjectlg] => 99
[subjectcre] => 3
) )
As you can see, 'studentextendID' is duplicated on both arrays, when it should be dynamically obtained, for example: 143 and 144, because there are two rows in the table with the same 'studentID'
You can try with change in model
public function update_batchs($table, $data)
{
if ($data) {
return $this->db->update_batch($table, $data, 'studentextendID');
}
}
You are not pass the $studentextendID in for loop.You need to pass this in for loop.
$studentextendID = $this->data['student']->studentextendID;
And also please verify $this->data['student'].

how to get last id after insert db in php

here I save data to the database with multiple rows, I want to retrieve each last id per row, how do I do that?
ex : print_r result when input data.
Array
(
[0] => Array
(
[name] => metode 11
[description] => DESC 1
)
[1] => Array
(
[name] => metode 22
[description] => DESC 2
)
[2] => Array
(
[name] => metode 33
[description] => DESC 1
)
)
in database
id | name | description
1 metode 11 desc 1
2 metode 22 desc 2
3 metode 33 desc 3
after finished input I want to take each id
and this my code
$data = array();
$numrow = 1;
foreach ($sheet as $row) {
if ($numrow > 1) {
array_push($data, array(
'name' => $row['A'],
'description' => $row['B'],
));
}
$numrow++;
}
$this->db->insert_batch('my_tabel', $data);
$myid =$this->db->insert_id();
//after insert i retrieve id using last_id() function, however, only last id is fetched, i want to fetch each id
$data_1 = array();
$numrow2 = 1;
foreach ($sheet as $row) {
if ($numrow2 > 1) {
array_push($data_1, array(
'id_last' => $myid,
'id' => $row['E'],
'barang' => $row['F'],
));
}
$numrow2++;
}
i want like this :
Array
(
[0] => Array
(
[last_id] => 1
[id] => 33
[barang] => ccc
)
[1] => Array
(
[last_id] => 2
[id] => 44
[barang] => dd
)
[2] => Array
(
[last_id] => 3
[id] => 55
[barang] => eee
)
)
thanks in advance for those who have answered
I hope what I said was clear enough
Why not insert it row by row instead of a batch?
Build a dictionary from each insert to pair it back later on.
$data = array();
$numrow = 1;
foreach ($sheet as $row) {
if ($numrow > 1) {
array_push($data, array(
'name' => $row['A'],
'description' => $row['B'],
));
}
$numrow++;
}
$array_of_insert_id = array();
foreach ($data as $index => $data_to_insert) {
$this->db->insert('my_tabel', $data_to_insert);
$array_of_insert_id[$index] = $this->db->insert_id();
}
$data_1 = array();
$numrow2 = 1;
$counter = 0;
foreach ($sheet as $row) {
if ($numrow2 > 1) {
array_push($data_1, array(
'id_last' => $array_of_insert_id[$counter],
'id' => $row['E'],
'barang' => $row['F'],
));
}
$numrow2++;
$counter++;
}
//table field with input field data array
$table_data = [
'table_field1' => $input_data1,
'table_field2' => $input_data2,
];
//insert data in database
$this->db->insert('table_name',$table_data);
//after insert return id
return $inserted_id = $this->db->insert_id();

Contrast 2 arrays in php

So I have 2 arrays in PHP, one with the following structure:
$tables
Array
(
[0] => Array
(
[id] => 206
[number] => 150
[capacity] => 4
[booking_code] => qhJEHcWnzty062DD
[reservation_date] => 2020-07-09 01:00:00
[start_time] => 12:30:00.000000
[end_time] => 14:15:00.000000
)
[1] => Array
(
[id] => 206
[number] => 150
[capacity] => 4
[booking_code] => ym9dP1aZtFstP3WM
[reservation_date] => 2020-07-22 01:00:00
[start_time] => 20:00:00.000000
[end_time] => 21:45:00.000000
)
)
The second array is the same structure but with a lot more rows which is $tablesWithDate.
I want to create a function that returns an array which is basically the second one, minus the data in the first one. So array1 = (1, 2, 3 , 4); array2 = (1, 4) I'd like the result to be array3 = (2, 3).
Here is my attempt thus far
function availableTables($tables, $tablesWithDate) {
$tablesReturn = array();
for($i = 0; $i < sizeof($tables); $i++) {
if($tables[$i]['table_no'] != $tablesWithDate[$i]['number']) {
$tablesReturn[] = array(
"table_no" => $tables[$i]['table_no']
);
}
}
return $tablesReturn;
}
$tables = getAllTables($connection);
$tablesWithDate = getTablesWithBookingOnDate($connection, $date);
$tablesReturn = availableTables($tables, $tablesWithDate);
return $tablesReturn;
I'm getting like 200+ errors of undefined offset 2, 3 4, etc
EDIT
function availableTables($tables, $tablesWithDate) {
$tablesReturn = array();
foreach($tables as $table) {
foreach($tablesWithDate as $twd) {
if($table['table_no'] != $twd['number']){
$tablesReturn[] = array(
"table_no" => $table['table_no'],
"capacity" => $table['capacity']
);
}
}
}
return $tablesReturn;
}

PHP Counting inside an Array

I want to create a list where if its already in the array to add to the value +1.
Current Output
[1] => Array
(
[source] => 397
[value] => 1
)
[2] => Array
(
[source] => 397
[value] => 1
)
[3] => Array
(
[source] => 1314
[value] => 1
)
What I want to Achieve
[1] => Array
(
[source] => 397
[value] => 2
)
[2] => Array
(
[source] => 1314
[value] => 1
)
My current dulled down PHP
foreach ($submissions as $timefix) {
//Start countng
$data = array(
'source' => $timefix['parent']['id'],
'value' => '1'
);
$dataJson[] = $data;
}
print_r($dataJson);
Simply use an associated array:
$dataJson = array();
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (!isset($dataJson[$id])) {
$dataJson[$id] = array('source' => $id, 'value' => 1);
} else {
$dataJson[$id]['value']++;
}
}
$dataJson = array_values($dataJson); // reset the keys - you don't nessesarily need this
This is not exactly your desired output, as the array keys are not preserved, but if it suits you, you could use the item ID as the array key. This would simplify your code to the point of not needing to loop through the already available results:
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (array_key_exists($id, $dataJson)) {
$dataJson[$id]["value"]++;
} else {
$dataJson[$id] = [
"source" => $id,
"value" => 1
];
}
}
print_r($dataJson);
You should simplify this for yourself. Something like:
<?
$res = Array();
foreach ($original as $item) {
if (!isset($res[$item['source']])) $res[$item['source']] = $item['value'];
else $res[$item['source']] += $item['value'];
}
?>
After this, you will have array $res which will be something like:
Array(
[397] => 2,
[1314] => 1
)
Then, if you really need the format specified, you can use something like:
<?
$final = Array();
foreach ($res as $source=>$value) $final[] = Array(
'source' => $source,
'value' => $value
);
?>
This code will do the counting and produce a $new array as described in your example.
$data = array(
array('source' => 397, 'value' => 1),
array('source' => 397, 'value' => 1),
array('source' => 1314, 'value' => 1),
);
$new = array();
foreach ($data as $item)
{
$source = $item['source'];
if (isset($new[$source]))
$new[$source]['value'] += $item['value'];
else
$new[$source] = $item;
}
$new = array_values($new);
PHP has a function called array_count_values for that. May be you can use it
Example:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

How to output an array based on primary keys and foreign keys

Considering this array
Array
(
[0] => Array
(
[id] => 51
[category_id] => 37
[title] => Sims
)
[1] => Array
(
[id] => 37
[category_id] => 26
[title] => Blackberry
)
[2] => Array
(
[id] => 26
[category_id] => 0
[title] => Mobile Device
)
I would like to be able to print out:
Mobile Device > Blackberry > Sims
Based on the relationship between category_id and id.
Can you use the id as the key into the array? It will make your life a bit simpler. For example, if you define your array:
Array
(
[51] => Array
(
[id] => 51
[category_id] => 37
[title] => Sims
)
[37] => Array
(
[id] => 37
[category_id] => 26
[title] => Blackberry
)
[27] => Array
(
[id] => 26
[category_id] => 0
[title] => Mobile Device
)
Then you can write code like:
//assume $a is your array, defined above
//and that you have used the id for the array key
$id = 51
do {
print $a['title'];
$id = $a['category_id'];
}while($id != 0);
EDIT: array_multisort probably isn't cleanest way to do this.
<?php
$array = Array(
array('id' => 51, 'category_id' => 37, 'title' => 'Sims'),
array('id' => 37, 'category_id' => 26, 'title' => 'Blackberry'),
array('id' => 26, 'category_id' => 0, 'title' => 'Mobile Device'));
// First build an associative array ID->Object
$map = array();
foreach( $array as $value )
{
$map[$value['id']] = $value;
}
// Then build your path
$path = array();
$value = $array[0];
while( true )
{
$path[] = $value['title'];
if( $value['category_id'] == 0 )
{
break;
}
$value = $map[$value['category_id']];
if( !isset($value) )
{
die("Data Inconsistency");
}
}
// Display path
echo implode(array_reverse($path), ' > ');
?>
Try array_multisort()
Does your original array also contains entries that are to be left out?
If not, use this:
$sort_array = array();
foreach ($original_array as $key => $value) {
$sort_array[] = $value['category_id'];
}
array_multisort($sort_array, SORT_ASC, $original_array);
The above will sort $original_array based on the category_id index.
If your array contains entries that have nothing to do with the rest, and you want to leave them out, you have to use something like this:
// remap keys based on category_id
$parts = array();
foreach ($original_array as $array) {
$parts[$array['category_id']] = $array;
}
// build tree list
$category_id = 0;
$result = array();
while (isset($parts[$category_id])) {
$result[] = $parts[$category_id]['title'];
$category_id = $parts[$category_id]['id'];
}
echo implode(' > ', $result);

Categories