I'm retrieving some hierarchical data from an Oracle database using the "connect by" function.
Then I populate a PHP array with the result of my query looking like:
while ($row_branches = oci_fetch_array($query_tree)) {
$tree[] = array(
'id' => $row_branches['ID']
, 'parent' => $row_branche['PARENT']
, 'data' => htmlspecialchars($row_branches['NAME'])
, 'level' => $row_branches['LEVEL']
);
}
The field ID is the unique id of the row
The field PARENT is the ID of the parent
The field DATA is the name of the item
The field LEVEL is the level of the row in the hierarchy.
I'd rather have a multidimensional array because my goal is to use the PHP function json_decode().
The depth of the hierarchy is never known in advance.
So my question is:
How could I populate a multidimensional array with the result of my query?
Thanks a million in advance for your answers.
try this
function adj_tree(&$tree, $item) {
$i = $item['ID'];
$p = $item['PARENT'];
$tree[$i] = isset($tree[$i]) ? $item + $tree[$i] : $item;
$tree[$p]['_children'][] = &$tree[$i];
}
$tree = array();
while ($row = oci_fetch_array($query_tree)) {
adj_tree($tree, $row);
Related
I am looking at trying to build pagination method for an array. I have an array something like below. Before you suggest making the pagination work for sql query, I have already done so and it did work for a flat array but a requirement is having this multidimensional tree array.
array = (
item_id = 5,
parent_id = 0,
children = array(
array(
item_id = 20,
parent_id = 5,
children = array(
array(
item_id = 24,
parent_id = 20
),
array(
item_id = 24,
parent_id = 20
)
)
)
)
);
What methods that I can find don't seem to work with such an array since array_slice will only work on the first level of the array and doesn't take into consideration the children levels.
/*
$root =
[
'id' => 1,
'children' => [...]
]
$queue[] = $root
$visiteds[] = $root
while ($queue){
$current = array_shift($queue);
// do whatever with the current ex: echo $current."<br>"
if $current has children {
foreach child {
if ($child NOT in $visiteds) { // $child not visited before
$visiteds[] = $child // mark as visited
$queue[] = $child // add to queue
// do whatever with the child ex: echo $child ."<br>"
}
}
}
}
*/
Note: if you want to visit exactly same children as required (for example 2 exactly same child must be visited twice then, remove $visiteds related parts. In this case be careful that your graph structure must not have cycling.)
You may consider to read about Graph Theory, Breadth First Search algorithm, Depth First Search algorithm.
I have an object where there are all my articles.
I'm currently looping my object to fill an array where I create an associative table for each article.
In my object I also have a Categories object and I would like to add the label of each category at the end of each associative array previously completed, but
I don't know how to do that.. In the Categories object there may be multiple labels.
My code :
$articles = $this->entityManager->getRepository('SGBundle:Article')->findBy([], ['id'=>'desc']);
$arrayCollection = [];
foreach($articles as $article) {
$arrayCollection[] = [
'id' => $article->getId(),
'date_publication' => $article->getDatePublication(),
...
];
foreach($article->getCategories() as $categorie) {
$arrayCollection[] = ['categorie' => $categorie->getLibelle()];
}
}
On my screenshot, for each article there is an array with 36 values and an array with 1 value and I would like this table to be in the table where there are 36 values. It's possible ?
First gather categories, then add'em to article item:
foreach($articles as $article) {
$categories = [];
foreach($article->getCategories() as $categorie) {
$categories[] = $categorie->getLibelle();
}
$arrayCollection[] = [
'id' => $article->getId(),
'date_publication' => $article->getDatePublication(),
...
//
'categorie' => $categories,
];
}
If the article.categories field is marked as lazy, then it won't be hydrated by default and the $article->getCategories() will perform a new query on each loop round.
Instead of a simple findBy, you might want a custom DQL query in this case to optimize this and get the exact array you want in one single request.
Also note that your current query is fetching all articles of your database. While this is probably your purpose, keep in mind that this could get pretty heavy with the data growing. In most cases, this kind of query should be paginated.
Using php-mysql, I am fetching data, pushing it into an array. An array consists of 486 records. It's an associative array with 7 column for each record.
When there is a GET request, it works fine. Getting data, binding it to table, chart and dropdown. Everything works fine.
I need to populate dropdown based on selection of another dropdown. And in that case I am making a POST request. And searching in the same array of 486 records.
$temp = Array();
$teamSelectData = Array();
foreach ($allBookingsData as $key => $value) {
if($value['PDG'] == $passedPDG){
array_push($temp, $value["Team_Name"]);
}
}
$tempTeam = array_iunique($temp);
foreach ($tempTeam as $key => $value) {
array_push($teamSelectData, Array(
'name' => $value,
'value' => $key,
'title' => $value
));
}
$returnArray['TeamSelectData'] = $teamSelectData;
// get unique items from array
function array_iunique($array) {
$upper = array_map('strtolower', $array);
return array_intersect_key($array, array_unique($upper));
}
I couldn't able to figure out why is it taking too much time to execute. The comparison if($value['PDG'] == $passedPDG) is the issue or the function array_iunique. And the same way I am populating dropdown for PDG. Based on a selection of PDG, I need to fill dropdown of Team.
How to make this function efficient ?
I have an array of the names of my POST variables to use when I update a row in my database.
$jobs = array( "proposal_id",
"will_provide",
"general_scope",
"per_bid",
"job_type");
Using this style my table is called jobs and each value in the array is a column id.
I want to edit this array so each item (column id) contains a single _POST Value
Then I have a function that uses the variables to create generic queries.
function save_data($jobs) {
foreach ($jobs as $job)
{
$job[$job[$i]] = _$Post[$job];
or
Table_name[column] = cell value;
...
...
...
I would like to be able to save $values into the post variables associated to it. Something like
For example if I was going to manually create this array it would look like
$jobs = array('proposal_id' => '12345678','title_of_project' => 'aTitle','creator' => 'aUser','last_modified' => '0000-00-00','date_created' => '0000-00-00','price' =>'1000');
This should be what you're looking for:
$jobs = array( "proposal_id",
"will_provide",
"general_scope",
"per_bid",
"job_type");
$jobValues = array();
foreach($jobs as $job) {
$jobValues[] = isset($_POST[$job]) ? $_POST[$job] : null;
}
$jobs = array_combine($jobs, $jobValues);
So I have my query, its returning results as expect all is swell, except today my designer through in a wrench. Which seems to be throwing me off my game a bit, maybe its cause Im to tired who knows, anyway..
I am to create a 3 tier array
primary category, sub category (which can have multiples per primary), and the item list per sub category which could be 1 to 100 items.
I've tried foreach, while, for loops. All typically starting with $final = array(); then the loop below that.
trying to build arrays like:
$final[$row['primary]][$row['sub']][] = $row['item]
$final[$row['primary]][$row['sub']] = $row['item]
I've tried defining them each as there own array to use array_push() on. And various other tactics and I am failing horribly. I need a fresh minded person to help me out here. From what type of loop would best suit my need to how I can construct my array(s) to build out according to plan.
The Desired outcome would be
array(
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
)
Something like this during treatment of your request :
if (!array_key_exists($row['primary'], $final)) {
$final[$row['primary']] = array();
}
if (!array_key_exists($row['sub'], $final[$row['primary']])) {
$final[$row['primary']][$row['sub']] = array();
}
$final[$row['primary']][$row['sub']][] = $row['item'];
Something like this....
$final =
array(
'Primary1'=>array(
'Sub1'=>array("Item1", "Item2"),
'Sub2'=>array("Item3", "Item4")
),
'Primary2'=>array(
'Sub3'=>array("Item5", "Item6"),
'Sub4'=>array("Item7", "Item8")
),
);
You can do it using array_push but it's not that easy since you really want an associative array and array_push doesn't work well with keys. You could certainly use it to add items to your sub-elements
array_push($final['Primary1']['Sub1'], "Some New Item");
If I understand you correctly, you want to fetch a couple of db relations into an PHP Array.
This is some example code how you can resolve that:
<?php
$output = array();
$i = 0;
// DB Query
while($categories) { // $categories is an db result
$output[$i] = $categories;
$ii = 0;
// DB Query
while($subcategories) { // $subcategories is an db result
$output[$i]['subcategories'][$ii] = $subcategories;
$iii = 0;
// DB Query
while($items) { // $items is an db result
$output[$i]['subcategories'][$ii]['items'][$iii] = $items;
$iii++;
}
$ii++;
}
$i++;
}
print_r($output);
?>