MVC multi-dim array displaying in view

By : tobzzz
Source: Stackoverflow.com
Question!

I can't think my way through this one. I'm still learning arrays so go easy on me. I'm using codeigniter.

I have 3 tabs (1 month, 2 month, 3 month) in my mark-up.

Each tab shows 3 price boxes (3 levels - basic=1, standard=2, featured=3).

I need to display 9 prices overall, pulled from 1 look-up:

return $this->db->get('prices')->result_array();

In the database it's like this

enter image description here

Should I be trying to do it from one look-up as shown in my model or should I be doing several look-ups, or should I just be managing that look-up in the controller setting vars, ready to display in the view or just doing everything in the view? And How? The only think of 3x foreach loops, where inside the loop I say:

if($prices['months']==3) echo $prices['level'].' is '.$prices['amount'].'<br>';

I'd like to know the BEST way to do this but also how to do the array from one look-up, because I think I really need to get my head around arrays properly. Thanks :)

-- EDIT to show what I've ended up using below --

In the controller, sort of inspired by array_chunk but more manual and to allow for the table to expand, is setting array keys which I read up on in php manual:

foreach ($prices as $price_row) {
    $data['prices'][$price_row['months']][] = $price_row;
}

Then in the view I can just use foreach for a month:

foreach ($prices[1] as $p) {
    echo level_name($p['level']).' = '.$p['amount'].'<br>';
}
By : tobzzz


Answers

In your controller,

    $result = $this->db->query("SELECT * from prices");
    $result=$result->result();
    $tab1=array();
    $tab2=array();
    $tab3=array();
    foreach ($result as $res) {
        switch($res->months)
        {
            case 1: array_push($tab1, $res);
            break;
            case 2: array_push($tab2, $res);
            break;
            case 3: array_push($tab3, $res);
            break;
        }
    }
    //var_dump($tab3); //array tab1 for month1, array tab2 for month2, array tab3 for month3
   $data['tab1']=$tab1;
   $data['tab2']=$tab2;
   $data['tab3']=$tab3;
   $data['include']=$this->load->view('myview', $data);  

In your view i.e myview in my case,

<?php
if(!empty($tab1))
{
    echo "Tab 1"."<br>";
    foreach($tab1 as $tb)
    {

      echo "For level ".$tb->level." price is ".$tb->amount."<br>";
  }
}
if(!empty($tab2))
{
    echo "Tab 2"."<br>";
    foreach($tab2 as $tb)
    {

      echo "For level ".$tb->level." price is ".$tb->amount."<br>";
  }
}
if(!empty($tab3))
{
    echo "Tab 3"."<br>";
    foreach($tab3 as $tb)
    {

      echo "For level ".$tb->level." price is ".$tb->amount."<br>";
  }
}



?>


Here's a pretty easy way to sort the db return into separate arrays and then display them. @caralot stole my thunder so I came up with this alternative.

Using your current model return $this->db->get('prices')->result_array(); and assigning it to $data.

$data = $this->db->functionName();
//You should check $data validity but I'm skipping that
$month1 = [];
$month2 = [];
$month3 = [];
foreach($data as $row)
{
    if($row['months'] === '1')
    {
        $month1[] = $row;
    }
    elseif($row['months'] === '2')
    {
        $month2[] = $row;
    }
    else
    {
        $month3[] = $row;
    }
}
echo "Month 1<br>";
foreach($month1 as $month){
     echo "Level ". $month['level'].' is '.$month['amount'].'<br>';
}
echo "Month 2<br>";
foreach($month2 as $month){
     echo "Level ".$month['level'].' is '.$month['amount'].'<br>';
}
echo "Month 3<br>";
foreach($month3 as $month){
     echo "Level ".$month['level'].' is '.$month['amount'].'<br>';
}

If your table was less ordered than what you show it would be necessary to add a $this->db->order_by('level', 'ASC'); call to the query.

By : DFriend


i did not test this so might have made a stupid error - but basically you can foreach through each of your products - make an array - and then use that array in your view.

    // in your model Note I am returning an object not an array 
    // and always check to make sure something got returned 
    if( ! $products = $this->db->get('prices')->result() )
    {
       return false: 
    } 
    else
    {     
    $prices = array(); 

    foreach($products as $product)
    {
       // append the months number to the word 'months' to make it clear
       $month =  $product->months . 'month' ; 

       // same with level 
       $level =  'level' . $product->level ; 

       // build the array
       $prices[$month][$level] = $product->amount ; 

    }//foreach

    return $prices ; 

   }//else

so then in your controller - make sure something came back from the model, assign it to data, then pass data to your view

   if( ! $data['prices'] = $this->somemodelname->returnPrices() )
   {
       $this->showError() ; 
   }
   else
   {
       $this->load->view('yourviewname', $data); 
   }  

and then in your view you could foreach or just echo out each price if it needs to follow some layout.

 echo '1 month level 1 $' . $prices['1month']['level1'] ; 

and remember your best friend when doing arrays is print_r wrapped in pre tags so like

  echo 'start prices <br> <pre>' ;
    print_r($prices) ;
   echo '</pre>' ;

opinions - its fine to build stuff in the controller and the view while you are developing and building out. but get in the habit of refactoring to your models. keep your controllers as clean and thin as possible. if your views need complicated data structures - build them in a model first. that way if something goes wrong - your controller can decide what to do. AND you don't have to check in your view if $prices is set and valid because you have already done it. this minimizes where things can go wrong.

By : cartalot


This video can help you solving your question :)
By: admin