Valid array gives php Invalid argument supplied for foreach() - php

I have the following foreach loop that gives me the invalid argument error:
$all_students = $this -> model_accounts -> get_students_on_account($account['account_id']);
foreach ($all_students as $student)
{
...
}
I tried to debug using print_r to check what the $all_students array looks like and I got this as a result:
Array
(
[0] => Array
(
[id] => 00062
[student_name] => Reckless
[student_surname] => Harmse
[acc_id] => 198
[dob] => 07-07-1993
[gender] => Male
[active] => 1
[has_pic] => 1
[avatar] => 106.jpg
[pic_ver] => 1
[student_identity_num] => 9307075052084
)
)
So the array is there and as seen in the print_r details, it is seen as an array.
I have looked at other similar questions and none of them could help.
Thanx in advance
Added:
Model function used to get the students
function get_students_on_account($account_id)
{
$data = '';
$this->db->where('acc_id', $account_id);
$q = $this->db->get('students');
if ($q->num_rows() > 0)
{
foreach ($q->result_array() as $row)
{
$row['dob'] = $this -> change_date_format($row['dob']);
$data[] = $row;
}
}
return $data;
}

In your function get_students_on_account, replace this:
$data = '';
by this:
$data = array();
This is needed to consistently return an array. You don't want to return a string. When it does, the problem that you described will occur.

Try this
$res = $q->result_array();
foreach ($res as &$row)
{
$row['dob'] = $this -> change_date_format($row['dob']);
}
return $res;

Try this
In Controller
$all_students = $this->model_accounts->get_students_on_account($account['account_id']);
if($all_students == false){
echo "Empty result";
}
else{
foreach ($all_students[0] as $student)
{
...
}
}
In Model
function get_students_on_account($account_id)
{
$query = $this->db->query("SELECT * FROM students WHERE acc_id = $account_id");
$result = $query->result_array();
$count = count($result);
if (empty($count)) {
return false;
}
else{
return $result;
}
}

Related

PHP - Find Specific Value in Array (multidimensional)

I have the an array, in which I store one value from the database like this:
$stmt = $dbh->prepare("SELECT token FROM advertisement_clicks WHERE (username=:username OR ip=:ipcheck)");
$stmt->bindParam(":username",$userdata["username"]);
$stmt->bindParam(":ipcheck",$ipcheck);
$stmt->execute();
$data = array();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
So, that gives me: array("token","token");
When I print it:
Array ( [0] => Array ( [token] => 677E2114AA26BA4351A686917652C7E1BA67A32D ) [1] => Array ( [token] => C42190F3D72C5BB6BB6B68488D1D4662A8D2A138 ) )
I then have a loop, that loops all the tokens. In that loop, I try to search for a specific token, and if it that token matches, it will be marked as "seen":
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['token'] === $id) {
return $key;
}
}
}
This is my loop:
$icon = "not-seen";
foreach($d as $value){
$token = $value["token"];
$searchParam = searchForId($token, $data);
if($searchParam == $token){
$icon = "seen";
}
}
However, searchForid() simply returns 0
What am I doing wrong?
Ok, here you can see a PHP fiddle that works
$data = array();
$data[] = array('token'=>'123');
$data[] = array('token'=>'456');
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['token'] === $id) {
return true;
}
}
return false;
}
$icon = "not-seen";
foreach($data as $value){
$token = $value["token"];
$searchParam = searchForId($token, $data);
if($searchParam){
$icon = "seen";
}
}
echo $icon;
It echos 'seen' which is expected since I compare the same array values, now assuming that your $d variable has different tokens, it should still work this way.
That means that your $d array does not contain what you claim it contains, could you print_r this variable and post it in your answer?

How can I convert a hierarchical tree to parent-child relationships?

At the moment, i'm creating a dynamic menu for my own CMS (practising) in PHP, but I don't know to save the data in my database.
Database structure:
menuitem_id
menu_id
menuitem_order
menuitem_name
menuitem_page_id
parent_menuitem_id
I do get this output as a hierarchical tree, but that isn't the desired format for storing it into my database:
Array
(
[0] => Array
(
[id] => 2
)
[1] => Array
(
[id] => 1
[children] => Array
(
[0] => Array
(
[id] => 3
[children] => Array
(
[0] => Array
(
[id] => 4
)
[1] => Array
(
[id] => 5
)
)
)
[1] => Array
(
[id] => 6
)
)
)
)
However, I want to convert this to a parent ID array with new fresh ID's (I will truncate the table and insert new data). Something like this:
Array
(
[0] => 0
[1] => 0
[2] => 2
[3] => 3
[4] => 3
[5] => 2
)
How can this be done?
Note: i have read this article, but I need the opposite code of it.
You need a recursive function:
function flattenHierarchicalArray($arr, $parentId = null) {
$items = array();
foreach ($arr as $item) {
$items[] = array('id' => $item['id'], 'parentId' = $parentId);
if (isset($item['children'])) $items = array_merge($items, flattenHierarchicalArray($item['children'], $item['id']));
}
return $items;
}
I think I have the solution combined with AlliterativeAlice's PHP code.
I'm using the Nestable plugin. That extension creates my hierarchical tree and sets it in a hidden field in my form (done by JavaScript). I updated this code to create new IDs by adding this code:
var nestable_update = function(e){
//added for updating old IDs
$(".dd-item").each(function(index){
$(this).data("id", index+1);
});
var list = e.length ? e : $(e.target),
output = list.data("output");
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable("serialize")));
} else {
output.val("JSON browser support required for this demo.");
}
};
$(".dd").nestable({
maxDepth:5
}).on("change", nestable_update);
nestable_update($(".dd").data("output", $("#nestable_output")));
I used your PHP code for getting the parentID (many thanks to AlliterativeAlice, because it's more efficient than my original PHP code):
function flatten_hierarchical_tree($arr, $parent_id=0) {
$items = array();
foreach ($arr as $item) {
$items[] = array('id' => $item['id'], 'parent_id' => $parent_id);
if (isset($item['children'])) $items = array_merge($items, flatten_hierarchical_tree($item['children'], $item['id']));
}
return $items;
}
For those who are interested in my final code. It works for storing the data in the database and build it again into a hierarchical tree + a printable tree for HTML.
JavaScript code for the nestable plugin:
var nestable_update = function(e){
$(".dd-item").each(function(index){
$(this).data("id", index+1);
});
var list = e.length ? e : $(e.target),
output = list.data("output");
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable("serialize")));
} else {
output.val("JSON browser support required for this demo.");
}
};
$(".dd").nestable({
maxDepth:5
}).on("change", nestable_update);
nestable_update($(".dd").data("output", $("#nestable_output")));
Database structure:
menuitem_id
menu_id
menuitem_order
menuitem_name
menuitem_page_id
parent_menuitem_id
PHP functions for building trees (format storing data in database + format getting data from database):
function create_flatten_hierarchical_tree($tree, $parent_id=0) {
$items = array();
foreach ($tree as $item) {
$items[] = array("id" => $item["id"], "parent_id" => $parent_id);
if (isset($item["children"])) $items = array_merge($items, create_flatten_hierarchical_tree($item["children"], $item["id"]));
}
return $items;
}
function create_hierarchical_tree($tree, $root=0) {
$return = array();
foreach($tree as $child => $parent) {
if($parent["parent_menuitem_id"] == $root) {
if(isset($tree[$child]["menuitem_id"]) === true){
$parent['children'] = create_hierarchical_tree($tree, $tree[$child]["menuitem_id"]);
}
unset($tree[$child]);
$return[] = $parent;
}
}
return empty($return) ? null : $return;
}
function print_hierarchical_tree($tree, $rows_pages) {
if(!is_null($tree) && count($tree) > 0) {
$return .= "<ol class='dd-list'>";
foreach($tree as $item){
$options = "";
foreach($rows_pages as $row_pages){
$selected = "";
if($row_pages["page_id"] == $item["menuitem_page_id"]){
$selected = "selected";
}
$options .= "<option value='".$row_pages["page_id"]."' $selected>".$row_pages["friendly_url"]."</option>";
}
$return .= "<li class='dd-item' data-id='".$item["menuitem_id"]."'><div class='dd-handle'>drag</div><div class='item_wrapper'><div class='item'><div class='item_title'>".$item["menuitem_name"]."</div></div><div class='item_sub'><div class='label_input'><label for='menuitem_name".$item["menuitem_id"]."'>Menuitem name</label><input type='text' id='menuitem_name".$item["menuitem_id"]."' name='menuitem_name[]' value='".$item["menuitem_name"]."' /></div><div class='label_input'><label for='page_link".$item["menuitem_id"]."'>Page link</label><label class='select'><select id='page_link".$item["menuitem_id"]."' name='menuitem_page_id[]'>".$options."</select></label></div> <a onClick='delete_menuitem(".$item["menuitem_id"].");' class='button red_bg delete'>Delete</a></div></div>";
$return .= print_hierarchical_tree($item["children"], $rows_pages);
$return .= "</li>";
}
$return .= "</ol>";
}
return empty($return) ? null : $return;
}
Core code of menu_edit.php page:
<?php
$stmt_menuitems = $dbh->prepare("SELECT * FROM inno_mw_thurs_menuitems mi WHERE mi.menu_id=:menu_id");
$stmt_menuitems->bindParam(":menu_id", $_GET["menu_id"]);
$stmt_menuitems->execute();
if (!empty($stmt_menuitems->rowCount())) {
?>
<div class="dd">
<?php
$result = $stmt_menuitems->fetchAll();
$tree = create_hierarchical_tree($result);
$stmt_pages = $dbh->prepare("SELECT * FROM inno_mw_thurs_pages");
$stmt_pages->execute();
$rows_pages = $stmt_pages->fetchAll();
$tree = print_hierarchical_tree($tree, $rows_pages);
echo $tree;
?>
</div>
<?php
}
Core code of menu_edit_process.php page:
if(isset($_POST["menu_id"])){
$menu_id = $_POST["menu_id"];
$nestable_output = json_decode($_POST["nestable_output"], true);
$parent_menuitem_ids_arr = create_flatten_hierarchical_tree($nestable_output);
$stmt = $dbh->prepare("TRUNCATE TABLE inno_mw_thurs_menuitems");
$stmt->execute();
$stmt = $dbh->prepare("INSERT INTO inno_mw_thurs_menuitems (menu_id, menuitem_order, menuitem_name, menuitem_page_id, parent_menuitem_id) VALUES (:menu_id, :menuitem_order, :menuitem_name, :menuitem_page_id, :parent_menuitem_id)");
$menuitem_order_arr = array();
foreach($_POST["menuitem_name"] as $f => $name){
$menuitem_name = $_POST["menuitem_name"][$f];
$menuitem_page_id = $_POST["menuitem_page_id"][$f];
$parent_menuitem_id = $parent_menuitem_ids_arr[$f]["parent_id"];
if(array_key_exists($parent_menuitem_id, $menuitem_order_arr) && $parent_menuitem_id != 0){
$menuitem_order_arr[$parent_menuitem_id] += 1;
}
else{
$menuitem_order_arr[$parent_menuitem_id] = 0;
}
$stmt->bindParam(":menu_id", $menu_id);
$stmt->bindParam(":menuitem_order", $menuitem_order_arr[$parent_menuitem_id]);
$stmt->bindParam(":menuitem_name", $menuitem_name);
$stmt->bindParam(":menuitem_page_id", $menuitem_page_id);
$stmt->bindParam(":parent_menuitem_id", $parent_menuitem_id);
$stmt->execute();
}
header("location: menus_list.php");
}
Please, feel free to improve this code.

PHP foreach to make query

I have an array like this
Array ( [12313] => 1 [12312] => 1 ) 1
The array keys are the items that exist in the warehouse and values are the number of items.
I would like to check if the items and amounts actually exist in the warehouse database using php. I thought maybe I could use a foreach for each item check but I don't know how to use foreach. I would like to make a query like:
$query=$this->db->query("SELECT COUNT(*) as amount FROM warehouse where item=12313");
$check=$query->row_array();
$amt=$check['amount'];
if($amt>0){
return true;
}
else{
return false;
}
$array=array ( '12313' => 1,'12312' => 1 );
foreach($array as $k=>$val)
{
$query=$this->db->query("SELECT COUNT(*) as amount FROM warehouse where item='".$k."'");
$check=$query->row_array();
$amt=$check['amount'];
if($amt>0){
return true;
}
else{
return false;
}
}
Are you looking for something like:
$items = array(
12313 => 1,
12312 => 1,
);
foreach ( $items as $key => $value ) : //iterate over array
$query = "SELECT COUNT(*) as amount FROM warehouse where item = $key";
$check = $query->row_array();
$amt = $check['amount'];
if( $amt>0 ) {
return true;
}
else {
return false;
}
endforeach;
try this
$arr = array("[12313]" => "1" ,"[12312]" => "2");
foreach ($arr as $key=>$value) {
$query="SELECT COUNT(*) as amount FROM warehouse where item='".$key."'";
$check=$query->row_array();
$amt=$check['amount'];
if($amt>0){
return true;
}
else{
return false;
}
}
$array = array('12313' => 1, '12312' => 1);
foreach ($array as $key => $value) {
$this->db->select('COUNT(*) as amount');
$this->db->from('warehouse');
$this->db->where('item', $key);
$result = $this->db->get()->row_array();
return ($result['amount'] >= $value) ? TRUE : FALSE; //match no of items
// return ($result['amount'] > 0) ? TRUE : FALSE; //OR if just check the count
}

Check if values in mysql database exist in multi dimensional array

I have multiple ID's in an mysql database. I would like to know if there are ID's in the database which are not present in an multi dimensional array. For each ID which is not present in the multi dimensional array the row needs te be deleted. The following code is what I have so far.
function multi_array_search($search_for, $search_in) {
foreach ($search_in as $element) {
if ( ($element === $search_for) ) {
return true;
} elseif (is_array($element)) {
$result = multi_array_search($search_for, $element);
if($result == true)
return true;
}
}
return false;
}
$output = mysql_query("SELECT id FROM ads");
while ($g = mysql_fetch_array($output)) {
echo multi_array_search("$g", $arr) ? 'Found' : 'Not found';
}
I don't think the above code is correct for what I want?
Information:
The $arr looks like:
Array (
[0] => Array (
[url] => http://
[id] => 752
)
[1] => Array (
[url] => http://
[id] => 758
)
)
I tryed some solutions now and none of the mare working :(
Every thing seems to be fine. Just few updates to remove unwanted code from elseif and add one more check !empty into elseif condition.
function multi_array_search($search_for, $search_in) {
foreach ($search_in as $element) {
if ($element === $search_for){
return true;
}elseif(is_array($element) && !empty($element)){
$result = multi_array_search($search_for, $element);
}
}
return false;
}
$output = mysql_query("SELECT id FROM ads");
while ($g = mysql_fetch_array($output)) {
echo multi_array_search("$g", $arr) ? 'Found' : 'Not found';
}
Hope will help!
$removeid=array();
$idarray is the multi dimensional array you want to check your database id with.
$result = 'store your databse id here in the form of an array';
foreach ($result as $key => $value) {
$result=$value;
if(!empty($result))
{
foreach ($idarray as $key => $value) {
if ($value["id"] != $result) {
$removeid=$key;
}
}
}
}
now $removeid contains the id to be removed from the databse
$un_array = array();
foreach ($array as $h) {
$id = $h['id'];
array_push($un_array, $id);
}
$db_array = array();
$output = mysql_query("SELECT id FROM account WHERE account='$username'");
while ($g = mysql_fetch_assoc($output)) {
$id = $g['id'];
array_push($db_array, $id);
}
$result = array_diff($db_array, $un_array);
foreach ($result as $r) {
mysql_query("DELETE FROM account WHERE id='$r'");
}

MySQLi - search through an array

I have the following code:
function resultToArray($result) {
$rows = array();
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
// Usage
$query = 'SELECT q17, COUNT(q17) FROM tresults GROUP BY q17';
$result = $mysqli->query($query);
$rows = resultToArray($result);
//print_r($rows); // Array of rows
$result->free();
Brings back the following (only an excerpt):
Array ( [0] => Array ( [q17] => [COUNT(q17)] => 7 ) [1] => Array ( [q17] => Admin & Clerical [COUNT(q17)] => 118 )......etc.
What I am struggling with is how to then return the data, basically, what I need is some code to pull out the data as follows:
WHERE Array = Admin & Clerical BRING BACK THE COUNT(q17) number
How do I search through the array, normally, I'd use something like:
if($rows['q17']==$q[$i]){echo$rows['COUNT(q17)'];}
But this doesn't work - I assume because there are two sets of data within each part of the array? Not sure how to deal with this.
You can achieve this by using MYSQL itself, by using HAVING clause instead of WHERE.
To do this rewrite your query like this.
$query = 'SELECT q17, COUNT(q17) as qcount FROM tresults GROUP BY q17 HAVING q17="Admin & Clerical" ';
echo $row[0]['qcount']; //return 118
if you still want to it with PHP after getting the result from the database, it's how it done:
function get_q17_count($rows, $q17){
foreach ($rows as $onerow) {
if($onerow['q17'] == $q17){
return $onerow['COUNT(q17)'];
}
}
}
function resultToArray($results) {
$rows = array();
while($row = $results->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
// Usage
$querys = 'SELECT q17, COUNT(q17) FROM tresults GROUP BY q17';
$results = $mysqli->query($querys);
$rows = resultToArray($results);
//print_r($rows); // Array of rows
$results->free();
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['q17'] === $id) {
return $val['COUNT(q17)'];
}
}
return null;
}
Called the function using:
$id = searchForId($q[$i], $rows);echo " (".$id.")";

Categories