create a subcategories hierarchy from multidimensional array - php

I have this table in my DB (I hope it's correctly showed):
+++++++++++++++++++++++++++
| id_child |--| id_parent |
+++++++++++++++++++++++++++
| 5 |--| 2 |
| 6 |--| 2 |
| 7 |--| 4 |
| 8 |--| 4 |
| 9 |--| 5 |
| 10 |--| 5 |
| 11 |--| 9 |
| 12 |--| 9 |
---------------------------
I wrote a php recursive function that create a multidimensional array from a parent passed (in this case '2').
So, if I put a print_r I obtain this result:
Array ( [5] => Array ( [9] => Array ( [11] => Array ( ) [12] => Array ( ) ) [10] => Array ( ) ) [6] => Array ( ) )
How I can obtain a structure of this type?
(I exclude the first parent, 2)
(2)
-5
--9
----11
----12
--10
-6
Thanks.

You would need another recursive function to iterate over your array, like so:
function printCategories($categories, $level = 1) {
foreach ($categories as $cat => $subCats) {
echo str_repeat('-', $level) . $cat . "\n";
printCategories($subCats, $level+1);
}
}
printCategories($categories);

<?php
function printtree($tree, $level) {
$prefix=str_repeat('-',$level);
foreach ($tree as $k=>$v) {
echo "$prefix$k<br>\n";
if (is_array($v)) if (sizeof($v)>0) printtree($v,$level+1);
}
}
$tree=array( 5=>array(9=>array(11=>array(), 12=>array()), 10=>array()), 6=>array());
printtree($tree,1);
?>

Related

Count array elements based on criterias PHP

Looking for help in counting elements in a php array meeting certain criteria and getting them to properly display in html table.
I have this array named $Array
Array
(
[0] => Array
(
[fMonth] => 12
[fSnowDepth] => 0.2
)
[1] => Array
(
[fMonth] => 12
[fSnowDepth] => 3.7
)
[2] => Array
(
[fMonth] => 12
[fSnowDepth] => 1
)
[3] => Array
(
[fMonth] => 01
[fSnowDepth] => 1
)
[4] => Array
(
[fMonth] => 01
[fSnowDepth] => 0.5
)
[5] => Array
(
[fMonth] => 01
[fSnowDepth] => 4.5
)
[6] => Array
(
[fMonth] => 01
[fSnowDepth] => 1.3
)
)
What I'm trying to do is count the months which meet conditions such as fSnowDepth >= 1 and < 3, fSnowDepth >= 3 and < 5, etc. and place in html table. I'm expecting this with (blank) for the months with no count:
| Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
SD >=1 and < 3 | 2 | | | | | | | | | | | 1
SD >=3 and < 5 | 1 | | | | | | | | | | | 1
... etc depths | | | | | | | | | | | |
The code I have is:
$array = $result['rawSumSnowDepth'];
foreach ($array as $key => $items) {
if ($items['fSnowDepth'] >= 1 && $items['fSnowDepth'] < 3) {
$value = $items['fMonth'];
$output[$value] = ($output[$value] ?? 0) + 1;
for ($x = 0; $x <= 11; $x++) {
if ($x + 1 == $items['fMonth']) {
$result['snDaysOverAmt'][$x] = array($output[$value]);
} elseif (empty($result['snDaysOverAmt'][$x])) {
$result['snDaysOverAmt'][$x] = array($output[$value] => " ");
}
}
}
}
if (isset($result['snDaysOverAmt'])) {
foreach ($result['snDaysOverAmt'] as $amounts => $amount) {
if ($amount) {
echo '<td>' . implode($amount) . '</td>';
}
}
}
This code works like a charm for the first row of snow depths >= 1 and < 3 but when I run the code again for the next row (>= 3 and < 5) and I get what appears to be a doubling of the first row.
Is there another way to do this so I can include different snow depth counts AND is there a more concise way of doing this? I'm still a PHP rookie so any help would be appreciated.
Thanks to #Barmar this was all that was needed:
$output = [];
$result['snDaysOverAmt'] = [];
these were placed after the last closing bracket in the code provided in the question above.

Select where HSTORE value is $value Laravel

Using the query builder to try and select rows where a value in the HSTORE key $type is present.
My Where Statement:
->where("meta_data_fields->'$type'", 'like', '%'.$query.'%')
Not sure what I'm doing wrong. I get this error:
Undefined column: 7 ERROR: column "meta_data_fields->'Entity::hstore'" does not exist
Any ideas?
to get all records in table that have HSTORE
Model::where("meta_data_fields", 'like', '%'.$query.'%')->get();
This should do normally do the trick. In your case, data in meta_data_fields is a json string. if the search is performed on all rows in the table, will select all. So here is What I did,
I created a queryScope in the model
1 - fetch all data
2 - extract meta_data_field and decode it
3 - loop through meta_data_field
4 - select only that match the criteria and build the array
here is a table
+----+-------------+------------------------------------+-----------+
| id | name | desc | vendor_id |
+----+-------------+------------------------------------+-----------+
| 1 | apples | {"type":"fruit","origin":"mexico"} | 1 |
| 2 | oranges | {"type":"fruit","origin":"peru"} | 1 |
| 3 | Peaches | {"type":"fruit","origin":"mexico"} | 2 |
| 4 | Cherries | {"type":"fruit","origin":"us"} | 1 |
| 5 | banans | {"type":"fruit","origin":"brazil"} | NULL |
| 6 | Water Melon | {"type":"fruit","origin":"mexico"} | 1 |
+----+-------------+------------------------------------+-----------+
public function scopeItems($name ="mexico"){
$items = array();
$data = Self::get();
$meta_fields = json_decode($data -> pluck('desc') ,true);
foreach ($meta_fields as $key => $value) {
if (isset($value['origin']) && $value['origin'] == $name ){
$items[$key] = $data[$key] -> toArray();
}
}
return $items;
}
// output
Array
(
[0] => Array
(
[id] => 1
[name] => apples
[desc] => Array
(
[type] => fruit
[origin] => mexico
)
[vendor_id] => 1
)
[2] => Array
(
[id] => 3
[name] => Peaches
[desc] => Array
(
[type] => fruit
[origin] => mexico
)
[vendor_id] => 2
)
[5] => Array
(
[id] => 6
[name] => Water Melon
[desc] => Array
(
[type] => fruit
[origin] => mexico
)
[vendor_id] => 1
)
)
Hope this works for you this time.
So here's what worked in my situation with Laravel.
$result = \DB::select(\DB::raw("SELECT hstore_fields, id from table where lower(hstore_fields->'$type') like lower('%$query%')"));

Insert false data into database [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have multidimentions array hrefs :
Array
(
[1] => Array
(
[0] => http://213b572-ba681bf9cc9e
[1] => http://f057-4139-ac40-bc4449722ffc
[2] => http://b-c151-4ba1-b7b7-842771c36d6b
[3] => http://5a77fb-8fce-4793-868f-c9fd73524037
)
[2] => Array
(
[0] => http://8-d832-4b34-a55b-da04ad8cdd09
[1] => http://b38-6a60-4233-b207-f40fae2ef431
[2] => http://3-f31c-49c4-87ee-fcada05a105f
[3] => http://07514-e438-45e2-906e-b440cbcbf8dc
)
......
[76] => Array
(
[0] => http://8-d832-4b34-a55b-da04ad8cdd09
[1] => http://b38-6a60-4233-b207-f40fae2ef431
[2] => http://3-f31c-49c4-87ee-fcada05a105f
[3] => http://07514-e438-45e2-906e-b440cbcbf8dc
)
When i insert array hrefs above into database
foreach ($hrefs as $id_page => $href) {
foreach ($href as $value) {
mysqli_query($con, "INSERT INTO urls(`id`, `id_page`, `url`)
VALUES ('', '$id_page', '$value')");
}
}
mysqli_close($con);
I want my database are:
| id | id_page | url |
| 1 | 1 | http://jjjjjjjjj |
| 2 | 1 | http://jjjjjjjjj|
| 3 | 1 | http://jjjjjjjjj|
......
| 1000 | 76 | http://jjjjjjjjj|
but result:
| id | id_page | url |
| 1 | 1 | http://jjjjjjjjj |
| 2 | 1 | http://jjjjjjjjj|
| 3 | 1 | http://jjjjjjjjj|
......
| 500 | 35 | http://jjjjjjjjj|
| 501 | 1 | http://jjjjjjjjj|
When insert id_page loop to 35 and return begin 1.
$hrefs is multidimentions array like above. Any resolve?
I would try it this way :
foreach ($hrefs as $id_page => $href) {
foreach ($href as $value) {
mysqli_query($con, "INSERT INTO urls(`id_page`, `url`)
VALUES ('".$id_page."', '".$value."')");
}
}
mysqli_close($con);
Assuming "id" is set to auto_increment in your table.
Edit1: Check your data type in your "urls" table: maybe your "id_page" is too small to hold big values. Set it to int(11) for example.
Edit2: If there is any performance issue, you should execute only one query with multiple values, like that:
$sql = 'INSERT INTO urls(`id_page`, `url`) VALUES ';
foreach ($hrefs as $id_page => $href) {
foreach ($href as $value) {
$sql .= "('".$id_page."','".$value."'),";
}
}
$sql = substr($sql, 0, -1); // delete last comma
mysqli_query($con, $sql);
mysqli_close($con);

php Multidimensional array question

So I have an array like the following:
Array
(
[0] => Array
(
[user_id] => 684
[sec_id] => 2
[rank_id] => 1
[rank] => usr
)
[1] => Array
(
[user_id] => 693
[sec_id] => 3
[rank_id] => 5
[rank] => usr
)
)
And I have another array like this
Array
(
[0] => 2
[1] => 7
[2] => 27
)
I want the value of the second array to be added at the end of each arrays of the 1st array, and it should be multiplied. I mean, if I have 100 arrays in the first array, and 3 elements in the second array, I should have 300 in the resulting array.
Taking example of the above, I would like to have something as follows:
user_id | sec_id | rank_id | rank | menu_id
684 | 2 | 1 | usr | 2
684 | 2 | 1 | usr | 7
684 | 2 | 1 | usr | 27
693 | 3 | 5 | usr | 2
693 | 3 | 5 | usr | 7
693 | 3 | 5 | usr | 27
I tried with the following function, but it's not working.
function getR($arr_one,$arr_two) {
foreach ($arr_one as $k=>&$v) {
foreach ($arr_two as $x=>&$y) { $v['menu_id'] = $y; }
}
return $arr_one;
}
This is just making an array like this:
user_id | sec_id | rank_id | rank | menu_id
684 | 2 | 1 | usr | 27
693 | 3 | 5 | usr | 27
Means, it's just adding menu_id at the end of each element of the first array, but not multiplying. Any idea, I'm surely missing something.
Thanks guys.
function getR($arr_one,$arr_two) {
$new_arr = array();
foreach ($arr_one as $k=>$v) {
foreach ($arr_two as $x=>$y) {
$this_item = $v;
$this_item['menu_id'] = $y;
$new_arr[] = $this_item;
}
}
return $new_arr;
}
I'm not going to ask... but try this:
<?php
function crazy ($arr1,$arr2) {
foreach ($arr1 as $key=>$value) {
foreach ($arr2 as $value2) {
$nvalue=$value;
$nvalue[]=$value2;
$new[]=$nvalue;
}
}
return $new;
}
$arr1=array(array('user'=>1,'dude'=>2),array('user'=>2,'dude'=>3));
$arr2=array(2,7,27);
print_r(crazy($arr1,$arr2));
this is tested too, http://www.ideone.com/Of126
Without testing (eek!) I imagine something like this:
function getR( $arr_one, $arr_two )
{
$second_key = 0;
foreach ( $arr_one as $k => &$v )
{
$v['menu_id'] = $second_key++;
if ( 3 == $second_key ) $second_key = 0;
}
return $arr;
}
Presumably, you're passing the first array by reference? Not sure what $arr is that you're returning though...

How to retrieve tree nodes children (recursive function help)

I have a binary, the database table of relationships looks like this:
+----+----------+---------+-----+
| id | parentID | childID | pos |
+----+----------+---------+-----+
| 1 | 1 | 2 | l |
| 2 | 1 | 3 | r |
| 3 | 2 | 4 | l |
| 4 | 3 | 5 | r |
| 5 | 4 | 6 | l |
| 6 | 5 | 7 | r |
+----+----------+---------+-----+
I am able to extract or children of for example 1 - but I have very clumsy function for that, so I need something that works better.
The output I need should look like this:
Array
(
[0] => Array
(
[id] => 2
[parentID] => 1
[pos] => l
)
[1] => Array
(
[id] => 4
[parentID] => 2
[pos] => l
)
[2] => Array
(
[id] => 6
[parentID] => 4
[pos] => l
)
[3] => Array
(
[id] => 3
[parentID] => 1
[pos] => r
)
[4] => Array
(
[id] => 5
[parentID] => 3
[pos] => r
)
[5] => Array
(
[id] => 7
[parentID] => 5
[pos] => r
)
)
So far I came up with this function, however it returns nested array, I want it flattened ... but whenever I tried it it just fails.
function children($pid) {
//set sql
$sql = "SELECT * FROM relationships WHERE parentID = ".$pid;
//save query to result
$result = mysql_query ($sql)
or die("Bad request " . mysql_error());
while ($item = mysql_fetch_array($result)):
$topchild["id"] = $item["childID"];
$topchild["parentID"]= $item["parentID"];
$topchild["pos"] = $item["pos"];
$children[] = $topchild;
$children[] = children($item["childID"]);
endwhile;
return $children;
}
What do I do wrong there?
I want it flattened
$children[] = children($item["childID"]);
instead add each of the items in the return value separately:
foreach (children($item['childID'] as $child)
$children[]= $child;
(Also shouldn't $topchild be initialised inside the loop?)
If you are doing a lot of recursive queries like this, a parent-child relation table is not a good choice of data structure. Consider one of the hierarchically-oriented solutions such as nested sets.

Categories