Loading view inside a Library, issues with cached vars

194 Views Asked by At

I am trying to implement a widgets library using load->view. I know I can use include to call directly the file and avoid the vars cache issues but just wondering why it does not work.

Here is how I have structured my code:

My Controller:

class Page extends MY_Controller {

    public $data = array();

    public function __construct() {
        parent::__construct();
        ...
        $this->load->library('widgetmanager');
    }

    public function index($slug = '') {

        echo $this->widgetmanager->show(2);
        echo $this->widgetmanager->show(1);

    }
}

My Library

class WidgetManager
{

    private $CI;

    public function __construct()
    {
        $this->CI = & get_instance();
    }

    public function show($widget_id) {
        $data = array();
        $widget_id = (int)$widget_id;



        $this->CI->db->select('*');
        $this->CI->db->from('widget');
        $this->CI->db->where('id', $widget_id);

        $query = $this->CI->db->get();

        $item = $query->row_array();

        $data['widget_title'] = $item['title'];
        $data['widget_content'] = $item['content'];

        $widget =  $this->CI->load->view('widget/'.$item['source'], $data, TRUE);

        $data['widget_title'] = '';
        $data['widget_content'] = '';

        $this->CI->load->view('widget/'.$item['source'], $data);

        return $widget;
    }
}

widget 1: Calls widget/content
widget 2: Calls widget/banner

What is happening is, the vars set on the first widget call (they are same name as second widget call), get cached, meaning values from the first call are passed to same call. It is weird because are different views.

I have tried:

  • Using clear_vars(): $this->CI->load->clear_vars(), before and after doing load->view on the library.
  • Calling load->view with empty array, null, etc
  • Tried to add a prefix with the widget slug to the vars (that works, but I have to send in some way the prefix to the view, so it is not possible due cache issue)

Any ideas?

2

There are 2 best solutions below

8
DFriend On

Here is what should work.

(I took the liberty of simplifying your database call making it require much less processing.)

public function show($widget_id)
{
    $data = array();
    $widget_id = (int) $widget_id;

    $item = $this->CI->db
      ->get_where('widget', array('id' => $widget_id))
      ->row_array();

    $data['widget_title'] = $item['title'];
    $data['widget_content'] = $item['content'];

    $widget = $this->CI->load->view('widget/'.$item['source'], $data, TRUE);

    //clear the cached variables so the next call to 'show()' is clean
    $this->CI->load->clear_vars(); 

    return $widget;
}

On further consideration The call $this->CI->load->clear_vars(); is probably pointless because each time WidgetManager::show() is called the $data var is recreated with exactly the same keys. When the $data var is passed to load->view the new values of $data['widget_title'] and $data['widget_content'] will replace the values in the cached vars using those keys.

0
Begandroide On

I'm facing the same issue here and for debug purpose you can check the cached variables by CI load with this method:

$this->CI->load->get_vars();

It's useful to use after call Load method to know the cached vars. If you need clean this "cache" you can use the method exposed by @DFriend :

$this->CI->load->clear_vars();

If you don't wanna call this method, and take adventage of the cache, you can rewrite the variables.