+ Reply to Thread
Results 1 to 4 of 4

Thread: How to ease the way of storing configuration parameters

  1. #1
    Join Date
    Sep 2007
    Location
    Karlstad, Sweden
    Posts
    3,082
    Blog Entries
    7
    Rep Power
    42

    How to ease the way of storing configuration parameters

    Hello everyone.

    I'm been building a system of my own for a while now, and thaught of sharing some code with you. I'm building some kind of community, with users and stuff.
    In most systems, you need to have configuration parameters, that you can easily change, and especially if more people will be administrating the site, so you can build a web form to handle the parameters.

    Another usage of this code I will show you, is to store unlimited amount of facts of a user, no need to create another field in the user table!

    First, I have an MySQL Table to store my configuration in:

    [highlight="sql"]
    CREATE TABLE `base_config` (
    `scope` bigint(20) unsigned NOT NULL DEFAULT '0',
    `module` bigint(20) unsigned NOT NULL DEFAULT '0',
    `var` varchar(50) NOT NULL DEFAULT '',
    `value` varchar(250) DEFAULT NULL,
    PRIMARY KEY (`scope`,`var`,`module`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    [/highlight]
    This table has those 4 fields,
    • Scope - This is either a user id or the system
    • Module - as I have built a module based system, this can be used for any modules own' purposes, this is which module that has this particular information. if not used, just use 0, or remove it from everywhere.
    • Var - name of the variable you're looking for
    • Value - value of the variable stored

    I have choosen to store max 250 chars in these values. this can of course be altered after own wishes.

    Then, we need some PHP code to handle this table, I have choosen to do this as a class as it gets to be a solid configuration item, with no need to interfere with.

    The only thing to think about is the database. I have created a special class just to keep an database connection opened, how you solve it, is up to you. I continously use the OOP version of mysqli.

    This is my database class:
    Code:
    final class db {
        protected static 
    $_dbase null;
        public function 
    getInstance() {
            if (
    self::$_dbase === null) {
                
    self::$_dbase = new mysqli('db_host''db_user',
                     
    'db_password''db_name');
                if (
    mysqli_connect_errno()) {
                    echo 
    "Database Connection Error: " .
                         
    mysqli_connect_error();
                    exit(
    1);
                }
            }
            return 
    self::$_dbase;
        }

        protected function 
    __construct() {}
        protected function 
    __clone() {}
        protected function 
    __destruct() {
            
    self::$_dbase->close();
        }

    First, we declare the class and it's member variables. I declare them as protected, if we want to inherit this class some time.

    Code:
    class Config {
        protected 
    $module;
        protected 
    $user;
        protected 
    $conf;
        protected 
    $scope
    • module - will keep information about which module the instance will work for.
    • user - will hold all data for the logged in user
    • conf - will hold all module system data
    • scope - will keep which user we work with


    Now, we start creating an constructor, that is an function (method) that is ran when we create an instance for the class, and initiates the whole thing
    Code:
        public function __construct($module$scope 0) {
            
    $this->module $module;
            
    $this->scope $scope;
            
    $this->load();
        } 
    We take two parameters to create the class, we need to specify which module and which user we will handle, we store that in the member variables, then we call the load function, wich comes next.

    Code:
        public function load() {
            
    $db db::getInstance();
            if (
    $result $db->query("SELECT * FROM base_config WHERE scope = '0' AND module='" .
                
    $this->module "'")) {
                while (
    $row $result->fetch_assoc()) {
                    
    $this->conf[$row['var']] = $row['value'];
                }
                
    $result->close();
            } 
    Now, we load everything with scope 0, which means module system specific variables and store them in our array $conf. We let the method continue:
    Code:
            if ($this->scope != 0) {
                if (
    $result $db->query("SELECT * FROM base_config WHERE scope = '" $this->
                    
    scope "' AND module = '" $this->module "'")) {
                    while (
    $row $result->fetch_assoc()) {
                        
    $this->user[$row['var']] = $row['value'];
                    }
                    
    $result->close();
                }
            }
        } 
    So, if we have a user logged in, ie, scope set to something else but 0, we load as we did above, but into the user member instead.
    Now, we have all configuration needed for this run in memory.

    we declare a save method, to save modified variables.
    Code:
        public function save() {
            
    $db db::getInstance();
            
    $db->autocommit(false); 
    We get our db connection, and turn off autocommit, to be able to not modify the database until all changes are done

    we continue with saving the user variables:
    Code:
            if ($this->scope != 0) {
                
    $res $db->query("DELETE FROM base_config WHERE scope = '" $this->scope .
                    
    "' AND module = '" $this->module "'");
                
    $stat $db->prepare("INSERT INTO base_config VALUES ('" $this->scope "', '" .
                    
    $this->module "', ?, ?)");

                
    $stat->bind_param("ss"$var$value);

                foreach ((array )
    $this->user as $var => $value) {

                    
    $stat->execute();
                }
                
    $db->commit();
            } 
    First, we delete all of the data connected to this module and user, if a parameter was removed, then we reapply those in the stored variable

    and we repeat it all with the system parameters
    Code:
            $res $db->query("DELETE FROM base_config WHERE scope = '0' AND module = '" $this->
                
    module "'");
            
    $stat $db->prepare("INSERT INTO base_config VALUES ('0', '" $this->module .
                
    "', ?, ?)");
            
    $stat->bind_param("ss"$var$value);
            foreach ((array )
    $this->conf as $var => $value) {
                
    $stat->execute();
            }
            
    $db->commit(); 
    now, we turn autocommit back on so everything is back to normal
    Code:
            $db->autocommit(true);
        } 
    So, that was that method, so we save the data. now, we go more to the usage interface of the class

    Here is how we read out variables:
    Code:
        public function getVar($var) {
            if (isset(
    $this->user[$var])) {
                return 
    $this->user[$var];
            } else {
                return 
    $this->conf[$var];
            }
        } 
    If the user has it's own variable of the same name, use that instead of the system variable. this can be used for example background colors or themes or other things

    now, we want to be able to change a value:
    Code:
        public function setVar($var$value$scope 0) {
            if (!
    $scope) {
                
    $this->conf[$var] = $value;
            } else {
                
    $this->user[$var] = $value;
            }
        } 
    Don't forget to do a save(); when all variables are modified!

    if we wnat to remove it we use this unset, but here, we need to specify if we want to unset it from the user scope or the module scope
    Code:
        public function unsetVar($var$scope 0) {
            if (!
    $scope) {
                unset(
    $this->conf[$var]);
            } else {
                unset(
    $this->user[$var]);
            }
        } 
    If we ever wants to know which scope this is set up to, this reads it out.
    Code:
        public function getScope() {
            return 
    $this->scope;
        } 
    And this reads out which module...
    Code:
        public function getModule() {
            return 
    $this->module;
        } 
    At times, you might want all your variables in an array, so I built this one. I need to typecast the members to array, if someone of them are empty.
    Code:
        public function getArray() {
            return 
    array_merge((array )$this->conf, (array )$this->user);
        }

    end of class
    Attached Files Attached Files
    __________________________________________
    I study Information Systems at Karlstad University when I'm not on CodeCall

  2. CODECALL Circuit advertisement
    Join Date
    Always
    Location
    Advertising world
    Posts
    Many

     
  3. #2
    Join Date
    Aug 2009
    Location
    ~/
    Posts
    918
    Rep Power
    19

    Re: How to ease the way of storing configuration parameters

    Awesome +rep (when I can)

  4. #3
    Jordan Guest

    Re: How to ease the way of storing configuration parameters

    Nice looking code, Orjan! Yay for MySQLi.
    I'm curious, why do you turn autocommit off? The only time I've ever found commit and rollback useful was when manually executing SQL in a database (IE: From SQL Plus or MySQL Console). It would make sense if you caught a database error and rolledback but I don't see where you test for DB errors.

    +rep!

  5. #4
    Join Date
    Sep 2007
    Location
    Karlstad, Sweden
    Posts
    3,082
    Blog Entries
    7
    Rep Power
    42

    Re: How to ease the way of storing configuration parameters

    That is only because I don't want the table empty of it's contents too long time between the delete and the inserts, therefore, I hold the commits, and do all in a row later on. it might be milliseconds, but that could be when a user tries to read the database for a new page.
    __________________________________________
    I study Information Systems at Karlstad University when I'm not on CodeCall

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. First post, ease of use, and database consideration
    By President Legit in forum Java Help
    Replies: 0
    Last Post: 07-31-2010, 11:35 PM
  2. URL Parameters using / instead of ?
    By linuxprogramming4ever in forum PHP Development
    Replies: 6
    Last Post: 11-29-2009, 05:00 PM
  3. Value/Var Parameters Help
    By 2710 in forum Pascal and Delphi
    Replies: 1
    Last Post: 04-05-2009, 05:46 AM
  4. Default Parameters
    By Althaz in forum C# Programming
    Replies: 3
    Last Post: 11-21-2008, 10:59 AM
  5. SQL - Using parameters
    By reachpradeep in forum Database & Database Programming
    Replies: 0
    Last Post: 03-05-2007, 05:15 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts