Welcome Guest, Not a member yet? Register   Sign In
Session Data vs. Config Variables
#1

I need to store a couple of arrays to build a subnavigation for my site where the entries depend upon content beeing present.

This includes 14 subsections with 8 possible content sections each. Obviously I dont want to check for entries each page load and create 112 db-calls.

I will eventually use a heartbeat to update this in stored file (not sure how yet) but for the time beeing I tried out two options:

1) Session Data

Call the routine to check if entries are present and store the resulting array in the session Date. Upon subsequent calls the session data is used.

-> very fast but only on second page load onwards

2) This made me think storing this information globally is better.

a) use my controller and store an intial array as a session cookie i.e. $this->session->set_userdata([arrayname], [arraycontent]);

-> works obviously and runs on first page load if cookies are accepted

b) use config.php to specify array content i.e. $config['[arrayname]'] = array(
[arraycontent]
    );

and use a similar routine as above to check if the data is present. I sort of assume setting the date here would be faster as I dont have to run $this->session->set_userdata([arrayname], [arraycontent]); 14 times after defining the data.

My big question would be - which option is better practise?
Reply
#2

can you please describe the real world scenario so we can better imagine what you try to accomplish?

You mentioned that the "the entries depend upon content being present" Does it mean you just have to store the navigation tree in an array and display it if say $content is_set() and !empty() ? Or do you have to display different entries based on some other parameters in the content?
Reply
#3

You should try to find a way to avoid making 112 queries, one for each individual piece of content.

If menu is also built from database, you could use simple join to only select menu items that have linking content record available.

If menu is built on PHP side entierly, you could use sql IN statement to turn that 112 queries into 1 - SELECT id FROM content WHERE id IN (1, 2, ......list of checked IDs).
Reply
#4

(11-08-2018, 02:40 AM)qury Wrote: can you please describe the real world scenario so we can better imagine what you try to accomplish?

You mentioned that the "the entries depend upon content being present"  Does it mean you just have to store the navigation tree in an array and display it if say $content is_set() and !empty() ? Or do you have to display different entries based on some other parameters in the content?

sorry for beeing unclear. the menu builds dynamically.

the main content is seperated by categories i.e. News, Sports, Entertainment and any other category I create in the CMS.

each category can have 6 different sub-sections (i.e. europe, north-america, asia, etc.)

categories should only be displayed if they are created and sub-categories should only show if at least one content-item is in the database.

the menu populates itself dynamically by going through those steps:

1) get the categories that are currently set to active and order them alphabetically

2) for each categorie check if there any entries inside the sub-category. if at least one item is present, show the sub-category otherwise omit it from it the menu

the reason why i cant store the menu as an array after an initial call is that there is some custom settings if you are inside an actual view that shows just the categories + the sub-categories from the category the content is linked to so the actual layout changes from view to view.

I hope this makes it clear.
Reply
#5

(11-08-2018, 03:33 AM)Pertti Wrote: You should try to find a way to avoid making 112 queries, one for each individual piece of content.

If menu is also built from database, you could use simple join to only select menu items that have linking content record available.

If menu is built on PHP side entierly, you could use sql IN statement to turn that 112 queries into 1 - SELECT id FROM content WHERE id IN (1, 2, ......list of checked IDs).

Reducing the number of calls is exactly what i have done. By storing the values serverside i can omit all 112 queries and run a cronjob to update the count on a regular basis and never run it on a per user base. I have finished this so all i need to find out is where to place the information for optimal experience.

So I was wondering is wether I should pull those values into Session Data OR simply add them into the config variables. This is how I did it:

1) Session Data

Place the data in core/MY_Controller.php

class MY_Controller extends CI_Controller {
..
    // set default data
    protected function _set_default_data()
    {
    ..

   // set counts for navigation
        
        $sub_navigation_entries_1 = array(
        'A' => 1,
        'B' => 1,
        'C' => 1,
        'D' => 1,
        'E' => 1,
        'F' => 1,
        'G' => 1,
        'H' => 0
    );
        
        $this->session->set_userdata('sub_navigation_entries_1', $sub_navigation_entries_1);

etc. this is repeated for each category. So the array is defined and then placed in sesssion data and later cross checked against session data.

2) Place the data in application\config\config.php

just place the arrays there like

$config['sub_navigation_entries_1'] = array(
        'A' => 1,
        'B' => 1,
        'C' => 1,
        'D' => 1,
        'E' => 1,
        'F' => 1,
        'G' => 1,
        'H' => 0
);

And then pull it when I render the navigation in with a foreach loop:

$this->config->item('sub_navigation_entries_1');

I would think that option 2 will be cleaner and faster since you dont have to pull the data from the session or check wether the session value is set at all. The values are delivered trough config and just pulled out. Am I correctly assuming this is the best performing way to solve this?
Reply
#6

How would you implement option 2 - overwrite config.php file?
Reply
#7

(11-08-2018, 05:02 AM)Pertti Wrote: How would you implement option 2 - overwrite config.php file?

Fairly easy. In autoload.php I added this:

$autoload['config'] = array('sub_navigation_entries');

and placed sub_navigation_entries.php in the config folder. This contains just the arrays with the specific values.

Only thing left for me to do is to create a cronjob shedule the recreation of the file maybe every 3 hours or so. In case someone hits the a view while the file is written I have added a fallback to caching & database query into the menu-code.
Reply
#8

Ah right, so you don't overwrite config.php but you do write a file in config folder?

I'd be a bit careful with allowing PHP to write in that folder. If you're can't easily turn these 112 queries into one simple query then yeah, I suppose any kind of caching is solution to go with, either by auto-loading it via config, or having data file generated, lets say in JSON format, that can be loaded when you need it.
Reply
#9

(11-08-2018, 09:36 AM)Pertti Wrote: Ah right, so you don't overwrite config.php but you do write a file in config folder?

I'd be a bit careful with allowing PHP to write in that folder. If you're can't easily turn these 112 queries into one simple query then yeah, I suppose any kind of caching is solution to go with, either by auto-loading it via config, or having data file generated, lets say in JSON format, that can be loaded when you need it.

Thanks for the pointer. The problem is that I dont have any better idea to store the counts. Essentially they are needed to dynamically add new categories and their corresponding sub-categories and also to catch if for the first time a sub-category has gotten any entries. The best way to automate this without excessively calling the DB at least for the first load would be to store this in a an static file which is updated from time to time serverside so I dont have to babysit it. This provides a huge speed improvement and pushed controller execution time down to aroun 0.15 seconds from 1.2 seconds. The problem is that the site is super content rich and has several 100k entries which are sorted by sub-cats and linked to main cat since the entry can belong to several main-cats.

for now i have defined it in a custom config file. i failed to create a function to create this file on the spot though. I can get the arrays just fine and all but I have little experience in creating a file and saving it. this is my attempt - but it gives no linebreaks (lack of double quotes - but double quotes didnt work either....):

It's a protected function which only runs when a security token is passed and called serverside. I omit that code:

        // Load model
        $this->load->model('Page_m');
        
        // Prepare custom config file
        
        $custom_config_data = '<\?php ';
        $custom_config_data = $custom_config_data . 'defined(\'BASEPATH\') OR exit(\'No direct script access allowed\');';
        
        // get categories
        $categories= $this->Page_m->get(array('hidden' => 0, 'released' => TRUE), 'categories');
        
        foreach ($categories as $key_fow => $value_fow)
        {            
        $subentries = $this->Page_m->count_subnavigation($value_fow['id']);
       
       $subentries = json_encode($subentries);
        $subentries = str_replace('{', '(', $subentries);
        $subentries = str_replace('"A":', '\'A\' => ', $subentries);
        $subentries = str_replace('"B":', '\'B\' => ', $subentries);
        $subentries = str_replace('"C":', '\'C\' => ', $subentries);
        $subentries = str_replace('"D":', '\'D\' => ', $subentries);
        $subentries = str_replace('"E":', '\'E\' => ', $subentries);
        $subentries = str_replace('"F":', '\'F\' => ', $subentries);
        $subentries = str_replace('"G":', '\'G\' => ', $subentries);
        $subentries = str_replace('"H":', '\'H\' => ', $subentries);
        $subentries = str_replace('}', ');', $subentries);
        $subentries = str_replace('"', '', $subentries);
                
        $custom_config_data = $custom_config_data . '$config[\'sub_navigation_entries_' . $value_fow['id'] . '\'] = '. $subentries;

      }
      
      $custom_config_data = $custom_config_data . '?>';

       // Write config file
        //@file_put_contents('./application/config/test_sub_navigation_entries.php', $custom_config_data);
       echo $custom_config_data;

This works fairly OK but the first part of the custom_config_data doesnt show. When I run it, I get:

<\?php defined('BASEPATH') OR exit('No direct script access allowed')\;$config['sub_navigation_entries_1'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 0);$config['sub_navigation_entries_2'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 0);$config['sub_navigation_entries_3'] = ('A' => 1,'B' => 1,'C' => 0,'D' => 0,'E' => 0,'F' => 0,'G' => 0,'H' => 0);$config['sub_navigation_entries_4'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 0);$config['sub_navigation_entries_5'] = ('A' => 1,'B' => 1,'C' => 0,'D' => 0,'E' => 0,'F' => 0,'G' => 0,'H' => 0);$config['sub_navigation_entries_6'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 688);$config['sub_navigation_entries_7'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 0,'E' => 0,'F' => 0,'G' => 0,'H' => 0);$config['sub_navigation_entries_8'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 0);$config['sub_navigation_entries_9'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 0,'E' => 0,'F' => 0,'G' => 0,'H' => 0);$config['sub_navigation_entries_10'] = ('A' => 1,'B' => 1,'C' => 1,'D' => 1,'E' => 1,'F' => 1,'G' => 1,'H' => 0);$config['sub_navigation_entries_14'] = ('A' => 1,'B' => 0,'C' => 0,'D' => 0,'E' => 8,'F' => 0,'G' => 0,'H' => 0);?>

I must be tired but I dont see why I get <\?php instead of <?php.

Also I would very much to layout the output nicely or can I skip that.
Reply
#10

$custom_config_data = '<\?php ';
Reply




Theme © iAndrew 2016 - Forum software by © MyBB