PHP loop through multi-dimensional array - php

I am currently working on a site that is being built on codeigniter, I am currently querying the data at the moment I think there could be possible 3 arrays that could be returned as array each with a varying amount of results, my question I cannot for life of me loop through the array I have at the moment,
my model looks like this
public function get_special_backgrounds() {
$this->db->select('*');
$this->db->from('background');
$this->db->where('is_special', 1);
$query = $this->db->get();
return $query->result_array();
}
my controller
enter public function index() {
// $this->output->enable_profiler(TRUE);
$data = array();
if($query = $this->category_model->get_all_online()) {
$data['main_menu'] = $query;
}
$this->load->model('image_model');
/*
* Sort out the users backgrounds, basically do a check to see if there is a 'special' background
* if there is not a 'special' background then IF the user is logged in and has a background of there
* own show that one, if not show a generic one, if they are not logged in show a generic one
*/
$image = array();
if ($query = $this->image_model->get_special_backgrounds()) {
$image = $query;
}
$data = array_merge($data, $image);
die(print_r($data));
$this->load->view('home/main_page.php', $data);
}
the array the gets return looks like this,
Array
(
[main_menu] => CI_DB_mysql_result Object
(
[conn_id] => Resource id #28
[result_id] => Resource id #35
[result_array] => Array
(
)
[result_object] => Array
(
)
[current_row] => 0
[num_rows] => 1
[row_data] =>
)
[special] => Array
(
[0] => Array
(
[background_id] => 6
[background_name] => Master-Backgrounds.png
[background_path] => /Users/Simon/Sites/mysite/media/uploads/backgrounds/
[is_special] => 1
[background_date_uploaded] => 1262687809
[users_user_id] => 1
[users_user_group_group_id] => 1
)
[1] => Array
(
[background_id] => 11
[background_name] => Master-mysite-Template.png
[background_path] => /Users/Simon/Sites/mysite/media/uploads/backgrounds/
[is_special] => 1
[background_date_uploaded] => 1262795313
[users_user_id] => 5
[users_user_group_group_id] => 2
)
)
)
1

It's an object, so you can't loop through it like an array. I do see what you're trying to do and understand why it seems like that makes sense, but to see what I'm talking about, try this:
Change this:
public function get_special_backgrounds() {
$this->db->select('*');
$this->db->from('background');
$this->db->where('is_special', 1);
$query = $this->db->get();
return $query->result_array();
}
To this:
public function get_special_backgrounds() {
$this->db->select('*');
$this->db->from('background');
$this->db->where('is_special', 1);
$query = $this->db->get();
return $query;
}
AND
Change this:
$image = array();
if ($query = $this->image_model->get_special_backgrounds()) {
$image = $query;
}
To this:
if($images = $this->image_model->get_special_backgrounds()) {
foreach($images->result_array() as $image) {
echo "<pre>";
print_r($image);
echo "</pre></br >";
}
}

Do you need to loop on the special part of the array?
foreach ( $data['special'] as $row ) {
// do stuff with the $row array
}

Try foreach
$arr = (your array);
foreach ($arr as $key => $insideArrays) {
foreach ($insideArrays as $k2 => $insideInsideArrays){
..........
}
}

Looks like a result array, with an odd element at the beginning. I'd get rid of the first element and then just loop through it:
array_shift($data);
foreach ($data as $row) {
// Do stuff with $row
var_dump($row);
}

Related

How to get data from database by using an array of ids in codeigniter?

I have an id array in my controller that has checkbox input in a form in views. $toppings = $this->input->get('topping');
Array
(
[0] => 1
[1] => 3
[2] => 4
)
I'm trying to get the information relevant to each id in the array from the database.
$toppings = $this->input->get('topping');
foreach ($toppings as $topping ) {
$id = $topping;
$toppinglist = $this->toppingmodel->find_topping($id);
echo'<pre>'; print_r($toppinglist); die();
}
Model Class -
function find_topping($id)
{
$query = $this->db->get_where('Topping', array('id' => $id));
return $query->row_array(); }
}
The output array i'm getting is only the data for the first id
Array
(
[id] => 1
[slug] => mushroom
[toppingName] => Mushrooms
[price] => 50.00
)
How can i get all the data relevant to each id in an array. (nested array)
Thank you.
Controller:-
$toppings = $this->input->post('topping'); //Array
$toppinglist = $this->toppingmodel->find_topping($toppings);
model:-
function find_topping($idArr = array()){ //Array
$query = $this->db->where_in("Topping", $idArr)->get("tablename");
return $query->result_array();
}
Note:-
$idArr = array() means
make the function have a default value of array otherwise if something else is passed you'll get an error in your query.
You need to make your SQL query with WHERE IN().
In Codeignitor you can use $this->db->where_in($tableName, $arrayOfVales). Learn more here
Code Example
function find_topping(array $ids)
{
$query = $this->db->where_in('Topping', $ids);
return $query->result_array();
}

Search nested multidimensional array

I have a function that fills an array:
foreach ($request->get('ids') as $id) {
$pdfArray['other']++; // Yes this is initialized
$pdfArray['rows'][$i]['id'] = $schedule->getId();
$pdfArray['rows'][$i]['date'] = $schedule->getStart()->format('d.m.Y');
$pdfArray['rows'][$i]['dateSort'] = $schedule->getStart()->format('Y-m-d H:i');
$pdfArray['rows'][$i]['from'] = $schedule->getStart()->format('H:i');
$pdfArray['rows'][$i]['to'] = $schedule->getEnd()->format('H:i');
$pdfArray['rows'][$i]['desc'] = $schedule->getDescription();
}
What I want to do
On each loop, I want to check if the array (so far) already has a desc entry equal to the current $schedule->getDescription() AND the same date as $schedule->getStart()->format('d.m.Y') (actually more, but let's keep it simple)
What I tried
public function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && $this->recursive_array_search($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
Source
I use it like that:
if ($this->recursive_array_search($schedule->getDescription(), $pdfArray['rows']) &&
$this->recursive_array_search($schedule->getStart()->format('d.m.Y'), $pdfArray['rows'])){
$pdfArray['ma'][$schedule->getId()]++;
}
but this is true when ANY of the start or desc are SOMEWHERE in the current array.
How would I check if desc is found and start is in the SAME $i level?
EDIT for example
Let's say I have 10 $ids to loop through. After 2 loops, the $pdfArray looks like this:
Array
(
[other] => 2
[rows] => Array
(
[0] => Array
(
[id] => 1
[date] => 13.07.2016
[dateSort] => 2016-07-13 08:00
[from] => 08:00
[to] => 09:00
[desc] => TEST
)
[1] => Array
(
[id] => 2
[date] => 12.07.2016
[dateSort] => 2016-07-12 08:00
[from] => 08:00
[to] => 09:00
[desc] => TEST
)
)
)
The next iteration has the following:
$schedule->getStart()->format('d.m.Y') => 12.07.2016
$schedule->getDescription() => TEST
So I want to have the info that the combination already exists in the array.
BUT
$schedule->getStart()->format('d.m.Y') => 12.07.2016
$schedule->getDescription() => TEST2
should NOT return true upon checking of it exists.
To test for a "duplicate" you can use this function:
function testPresence($pdfArray, $desc, $date) {
foreach ($pdfArray["rows"] as $row) {
if ($row["desc"] == $desc && $row["date"] == $date) return true;
}
}
Example use:
echo testPresence($pdfArray, "TEST2", "12.07.2016") ? "Found" : "Not found"; // Not found
echo testPresence($pdfArray, "TEST", "12.07.2016") ? "Found" : "Not found"; // Found
In your original loop, you can use it as follows:
foreach ($request->get('ids') as $id) {
if (testPresence($pdfArray, $schedule->getDescription(),
$schedule->getStart()->format('d.m.Y')) {
// We have a duplicate. Maybe skip this entry?:
continue;
}
$pdfArray['other']++;
$pdfArray['rows'][$i]['id'] = $schedule->getId();
$pdfArray['rows'][$i]['date'] = $schedule->getStart()->format('d.m.Y');
$pdfArray['rows'][$i]['dateSort'] = $schedule->getStart()->format('Y-m-d H:i');
$pdfArray['rows'][$i]['from'] = $schedule->getStart()->format('H:i');
$pdfArray['rows'][$i]['to'] = $schedule->getEnd()->format('H:i');
$pdfArray['rows'][$i]['desc'] = $schedule->getDescription();
}
try this at your validation function
public function array_search($needle1, $needle2 ,$haystack) {
foreach($haystack as $singleArray){
if (in_array($needle1, $singleArray) && in_array($needle2, $singleArray))
return true;
else
continue;
}
return false;
}
and invoke your recursive_array_search like this
if ($this->array_search($schedule->getStart(), $schedule->getDescription(), $pdfArray['rows'])
continue;//Or any other kind of logic you want. At this place you know that description and date staet exist in at your array level
$pdfArray['other']++; // Yes this is initialized
$pdfArray['rows'][$i]['id'] = $schedule->getId();
$pdfArray['rows'][$i]['date'] = $schedule->getStart()->format('d.m.Y');
$pdfArray['rows'][$i]['dateSort'] = $schedule->getStart()->format('Y-m-d H:i');
$pdfArray['rows'][$i]['from'] = $schedule->getStart()->format('H:i');
$pdfArray['rows'][$i]['to'] = $schedule->getEnd()->format('H:i');
$pdfArray['rows'][$i]['desc'] = $schedule->getDescription();
Function version:
/**
* Find matches for $item into pdfArray.
* Returns an index array, possibly empty if no matches.
* #param $item item to find
* #param $rows rows where to search
*/
function findPdfArrayMatches(array $item, array $rows) {
return array_keys(
array_filter(
$rows,
function ($entry) use ($item) {
// These are the matching criteria. More than one row may match.
return $entry['desc'] == $item['desc']
&& $entry['date'] == $item['date']
;
}
)
);
}
You could do like this, in the loop:
$item = [
'id' => $schedule->getId(),
'date' => $schedule->getStart()->format('d.m.Y'),
'dateSort' => $schedule->getStart()->format('Y-m-d H:i'),
'from' => $schedule->getStart()->format('H:i'),
'to' => $schedule->getEnd()->format('H:i'),
'desc' => $schedule->getDescription(),
];
$matches = findPdfArrayMatches($item, $pdfArray['rows']);
if (!empty($matches)) {
...do something with the matches:
foreach ($matches as $match) {
$pdfArray['rows'][$match]['Duplicate'] = true;
}
}
// Add new item
$pdfArray['rows'][$i] = $item;

applying array_unique

I have code to get the address which is separated by space and then fetching area details about that address so each time sql result is stored in array "resultArray" and that result is pushed to another array "returnArray" which is then displayed in the format of json.I want to remove duplicate area_id in returnArray so I used "array_unique" but it's not working .Please give some suggestion.
Sample Code:
<?php
include_once 'main.php';
$dac = new Main();
$add = $_POST['address'];
$noLines = sizeof($add);
$resultArray=array();
$returnArray=array();
$returnArrayMain=array();
while ($noLines>0)
{
$resultArray=array();
$result = $dac->area_detail($add[$noLines-1]);
$count=mysql_num_rows($result);
while($row = mysql_fetch_assoc($result))
{
$resultArray[]=array('area_id' => $row['area_id'],'area_name' => $row['area_name'],'area_GISlat'=>$row['area_GISlat'],'area_GISlon'=>$row['area_GISlon']);
}
array_push($returnArray, $resultArray) ;
$noLines = $noLines-1;
}
$returnArrayMain = array_unique($returnArray);
echo json_encode($returnArrayMain);
?>
Here is solution with a testing associative array:
// this is testing array as you are using:
$resultArray = array(
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 11,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3')
);
// take a temporary arry
$temporaryArr = array();
// initialize key's array
$arrayKey = array();
foreach ( $resultArray as $key => $values ) {
if ( !in_array($values, $temporaryArr) ) {
$temporaryArr[] = $values; // store values in temporary array
$arrayKey[$key] = true; // store all keys in another array
}
}
// now use array_intersect_key function for intersect both array.
$requiredArr = array_intersect_key($resultArray, $arrayKey);
echo "<pre>";
print_r($requiredArr);
Result:
Array
(
[0] => Array
(
[area_id] => 12
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
[1] => Array
(
[area_id] => 11
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
)
Removed duplicate arrays.
From PHP Manual:
array_intersect_key — Computes the intersection of arrays using keys for comparison
Side note:
Also add error reporting to the top of your file(s) right after your opening <?php tag
error_reporting(E_ALL);
ini_set('display_errors', 1);
try this
$returnArrayMain = array_map("unserialize", array_unique(array_map("serialize", $resultArray)));
try this..
$returnArrayMain = uniqueAssocArray($returnArray, 'area_id');
echo json_encode($returnArrayMain);
function uniqueAssocArray($array, $uniqueKey) {
if (!is_array($array)) {
return array();
}
$uniqueKeys = array();
foreach ($array as $key => $item) {
$groupBy=$item[$uniqueKey];
if (isset( $uniqueKeys[$groupBy]))
{
//compare $item with $uniqueKeys[$groupBy] and decide if you
//want to use the new item
$replace= ...
}
else
{
$replace=true;
}
if ($replace) $uniqueKeys[$groupBy] = $item;
}
return $uniqueKeys;
}

Foreach array to update table of database use those element of array

How to get the first value of element of array in php.
My story board is like this:
I have an array like this:
(
[0] => Array
(
[ID] => 68
[MATERIAL] => I have
[AC] => Try
)
[1] => Array
(
[ID] => 69
[MATERIAL] => It
[AC] => No Surrender
)
)
I want to update some record on my database like this,
foreach element of array,
UPDATE MY TABEL SET MATERIAL = [MATERIAL], AC = [AC] where id= [id]
this is the model named m_admin :
public function update_eir_to_cost($id, $material, $ac) {
$data = array(
"MATERIAL" => $material,
"AC" => $ac);
$this->db->trans_start();
$this->db->where($id);
$this->db->update('tb_repair_detail', $data);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
// generate an error... or use the log_message() function to log your error
echo "Error Updating";
} else {
echo "Alhamdulillah";
}
}
This is the controller :
public function update_json_detail() {
$post_data = $this->input->post("POST_ARRAY");
$execute = array();
foreach ($post_data as $data) {
$execute[] = array(
'ID'=> $data['0'],
'MATERIAL' => $data['7'],
'AC' => $data['8']
);
}
echo "<pre>";
print_r($execute); // return an array like above.
/*forech element
update table using model
*/
}
This will solve your problem:
public function update_json_detail() {
$post_data = $this->input->post("POST_ARRAY");
$execute = array();
foreach ($post_data as $data) {
$execute[] = array(
'ID'=> $data['0'],
'MATERIAL' => $data['7'],
'AC' => $data['8']
);
}
echo "<pre>";
print_r($execute); // return an array like above.
$this->load->model('m_admin');
foreach ($execute as $row) {
$this->m_admin->update_eir_to_cost($row['ID'], $row['MATERIAL'], $row['AC']);
}
}

Create array of hierarchical directories in PHP

I have the following code (I know that this code is not optimized but it's not for discussion):
function select_categories($cat_id)
{
$this->db = ORM::factory('category')
->where('parent', '=', $cat_id)
->find_all();
foreach ($this->db as $num => $category)
{
if($category->parent == 0)
{
$this->tmp[$category->parent][$category->id] = array();
}
else {
$this->tmp[$category->parent][$category->id] = array();
}
$this->select_categories($category->id);
}
return $this->tmp;
}
Function returns this array:
array(3) (
0 => array(2) (
1 => array(0)
2 => array(0)
)
2 => array(1) (
3 => array(0)
)
3 => array(2) (
4 => array(0)
5 => array(0)
)
)
But how should I change the code
else {
$this->tmp[$category->parent][$category->id] = array();
// ^^^^^^^^^^^^^^^^^^^^^^ (this bit)
}
To merge array[3] to array[2][3] for example (because array[3] is a subdirectory of array[2] and array[2] is a subdirectory of array[0][2]), so, I need to make this (when I don't know the level of subdirectories):
array (
0 => array (
1 => array
2 => array (
3 => array (
4 => array
5 => array
)
)
)
)
A long time ago I wrote some code to do this in PHP. It takes a list of entities (in your case, categories) and returns a structure where those entities are arranged in a tree. However, it uses associative arrays instead of objects; it assumes that the “parent” ID is stored in one of the associative array entries. I’m sure that you can adapt this to your needs.
function make_tree_structure ($nontree, $parent_field)
{
$parent_to_children = array();
$root_elements = array();
foreach ($nontree as $id => $elem) {
if (array_key_exists ($elem[$parent_field], $nontree))
$parent_to_children [ $elem[$parent_field] ][] = $id;
else
$root_elements[] = $id;
}
$result = array();
while (count ($root_elements)) {
$id = array_shift ($root_elements);
$result [ $id ] = make_tree_structure_recurse ($id, $parent_to_children, $nontree);
}
return $result;
}
function make_tree_structure_recurse ($id, &$parent_to_children, &$nontree)
{
$ret = $nontree [ $id ];
if (array_key_exists ($id, $parent_to_children)) {
$list_of_children = $parent_to_children [ $id ];
unset ($parent_to_children[$id]);
while (count ($list_of_children)) {
$child = array_shift ($list_of_children);
$ret['children'][$child] = make_tree_structure_recurse ($child, $parent_to_children, $nontree);
}
}
return $ret;
}
To see what this does, first try running it on a structure like this:
var $data = array (
0 => array('Name' => 'Kenny'),
1 => array('Name' => 'Lilo', 'Parent' => 0),
2 => array('Name' => 'Adrian', 'Parent' => 1)
3 => array('Name' => 'Mark', 'Parent' => 1)
);
var $tree = make_tree_structure($data, 'Parent');
If I’m not mistaken, you should get something like this out: (the “Parent” key would still be there, but I’m leaving it out for clarity)
array (
0 => array('Name' => 'Kenny', 'children' => array (
1 => array('Name' => 'Lilo', 'children' => array (
2 => array('Name' => 'Adrian')
3 => array('Name' => 'Mark')
)
)
)
Examine the code to see how it does this. Once you understand how this works, you can tweak it to work with your particular data.
Assuming you dont want any data/children tags in your array:
foreach ($this->db as $num => $category)
{
// save the data to the array
$this->tmp[$category->id] = array();
// save a reference to this item in the parent array
$this->tmp[$category->parent][$category->id] = &$this->tmp[$category->id];
$this->select_categories($category->id);
}
// the tree is at index $cat_id
return $this->tmp[$cat_id];
If you just need to retrieve the full tree out of the database, you can even simplify your query (get all records at once) and remove the recursive call in this function. You will need an extra check that will only set the $this->tmp[$catagory->id] when it does not exist and else it should merge the data with the existing data.

Categories