Member Avatar for iamthwee

Hi I am using codeigniter and I want to use a constant defined in the config>constant file.

For example, my color theme for my view might be blue, so I save this in the constants file.

define('blue', '#3fsefe');

Now I can use this in all my views... works fine.

But what should I do if I want to pull this constant from a database? If you will a dynamic constant. I've read online about extending the controller class

http://stackoverflow.com/questions/11446677/codeigniter-constants-in-application-config-constant-php-from-db-table

but that seems seriously stupid especially for migration purposes, update to new version.

I also thought about storing it as a session which is persistent across the pages... That works but, it seems retarded.

Any suggestions welcome.

Recommended Answers

All 7 Replies

Member Avatar for iamthwee

Hmm, I've decided to use a 'helper' as this seems less hackish and then call this in the view.

if ( ! function_exists('my_theme_options'))
{
    function my_theme_options($var)
    {
       $CI =& get_instance();
       $CI->db->select('value');
       $CI->db->from('themes');
       $CI->db->where('option', $var);

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

       foreach ($query->result() as $row) {
        echo $row->value;
       }

    }   
}

I'm leaving this thread open in case veedeo has a better suggestion.

You could create a library and use it to pull the constants from the database, for example, here the table:

CREATE TABLE `constants` (
  `name` varchar(255) NOT NULL,
  `value` varchar(255) DEFAULT NULL
) ENGINE=MyISAM;

 insert into constants(name, value) values('blue', '#0000ff');
 insert into constants(name, value) values('dodger blue', '#1e90ff');
 insert into constants(name, value) values('deep sky blue', '#00bfff');

 select * from constants;
+---------------+---------+
| name          | value   |
+---------------+---------+
| blue          | #0000ff |
| dodger blue   | #1e90ff |
| deep sky blue | #00bfff |
+---------------+---------+
3 rows in set (0.00 sec)

Create the file consts.php in /application/libraries/ and paste:

<?php

class Consts
{
    private $CI;

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

    private function setConstants()
    {
        $query = $this->CI->db->get('constants');
        foreach($query->result() as $row)
        {
            define((string)$row->name, $row->value);
        }

        return ;
    }
}

In alternative you could dynamically set a config item, so instead of:

define((string)$row->name, $row->value);

You would use:

$this->CI->config->set_item($row->name, $row->value);

In your controller constructor:

class Test extends CI_Controller {

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

In alternative you could place it in the /config/autoload.php.

Finally, in your view:

<?php

    echo blue;
    echo constant('dodger blue');

Or in case of the dynamic set:

<?php

    echo $this->config->item('blue');

To avoid conflicts & problems, I would use a prefix and underscores to replace the spaces, for example, instead of dodger blue:

echo color_dodger_blue;
// or
echo $this->config->item('color_dodger_blue');

BUT, since constants are not meant to change after the installation, I would create a script to generate the config file that will save the values. Otherwise it's pretty like creating variables and you will constantly pull the database.

Hope it helps, bye!

Docs:

Member Avatar for iamthwee

Thanks it looks nice but involves writing a construct for each controller.

All my views share a common header view, and inside I have inline css targeting the theme color, so using a helper seems less cumbersome.

Thanks it looks nice but involves writing a construct for each controller.

If you load the library in the autoload.php file then you don't need the constructor. Anyway, helper of library, in this case does not make much difference: when I started writing my first post I didn't read about your decision... :)

"Dynamic constant"? That is a first...

Your helper looks good. Just always remember that

$CI =& get_instance();

will call the CI's main controller class by reference. So, all of the native helpers and libraries are available and usable by the function if it is in helper and by the object and methods if it is in the library class.

$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');
//and many more

There are some occasions where only few of these native helpers and libraries are needed. I honestly believe that we should only reference the main or original CodeIgniter object as needed and only when necessary.

How about if we only need the database connection? Do we really need to drag the entire CI main controller to our simple helper to make it function to do its work? My take on this is maybe yes or maybe not. However, let us take a look at your helper codes below

 function my_theme_options($var)
        {
        $CI =& get_instance();
        $CI->db->select('value');
        $CI->db->from('themes');
        $CI->db->where('option', $var);
        $query = $CI->db->get();
        foreach ($query->result() as $row) {
        echo $row->value;
        }
        } 

The codes above looks pretty good to me. Can we make it a little conservative in terms of server resources usage? Sure we can, why not?

The codes above or helper function ONLY need the database class, and we can simplify it to something like this.

 function my_theme_options($var)
    {
   $this->load->database();
     ## do all your queries here as you normally would.
    }

The modified codes above will load the database class manually and not by referencing the main CI object.

In my humble opinion, we SHOULD ONLY do this

class AnyClass {

    public function __construct(){

        $CI =& get_instance();

    }

    public function one(){
        $CI->load->library('session');
        $CI->load->helper('url');

    }
    public function two(){

        $CI->config->item('base_url');
    }

    }

WHEN the method one and two specifically need more than two of the objects instantiated in the original initialization fo the main CI object, we can write the reference call in the constructor. In this case, durng the initialization of the object AnyClass, the CI main object is instantaneously available without crating a copy of it ( CI object).

Member Avatar for iamthwee

Very good points veedeo. I have make a bit of a confession in that I'm autoloading all those files in my config file.

Why because I'm still newish to codeigniter and it just helps the debugging process. I don't have to worry about loading that library in my controller.

Is it bad practice, probably because like you say it affects performance.

When I switch to a production envirnoment I'll probably reconsider loading a library one by one.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.