Loading view inside a Library, issues with cached

2019-08-19 13:52发布

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?

1条回答
一夜七次
2楼-- · 2019-08-19 14:27

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.

查看更多
登录 后发表回答