Saving configuration information using key value pairs

April 16, 2008

There are times when you need to save configuration information for a project. I get this requirement time and again. Since most of my projects are database driven, I decided to use a database table dedicated to save this config info. I also developed few functions to read and set these settings.

Setting up the database

First here’s the table structure. Pretty simple though it has 3 fields (ie: columns) per record. The ‘metaId’ field is set to auto increment. So that every time I add a new record I don’t have to worry about setting a record id. ‘metaKey’ hold the name of the variable, or the ‘key’ and ‘metaValue’ hold the value of the variable. In order to understand the ‘table_prefix’ best practice, please go here. It will explain the meaning of ‘$dbprefix’ and ‘$db’variables.

  1. CREATE TABLE `sls_config` (
  2.   `metaId` int(11) NOT NULL auto_increment,
  3.   `metaKey` varchar(50) NOT NULL,
  4.   `metaValue` varchar(50) NOT NULL,
  5.   KEY `metaId` (`metaId`)
  6. ) ENGINE=MyISAM COMMENT=’stores config information’;

Although I thought 50 characters are enough for a variable (and its value), you may need to increase/decrease that depending on your scenario. ‘int’ will make sure we will never run-out of variables; ie: it allows 65,536 key/value pairs ! You may need to index this with metaKey, but I didn’t because this only has 3 fields total.

Creating a new config variable

You can provide a metaValue at the time of creating a metaKey. If you do not provide one, 0 will be used.

  1. FUNCTION createMetaKey($metaKey, $metaValue=0)
  2. {
  3. /*
  4. Create a new key/value pair. If metaValue is not provided default = 0
  5. input :
  6.         metaKey, metaValue
  7. Output:
  8.         1 if success, -1 if duplicate found, 0 db write error
  9. */
  10. global $dbprefix,$db;
  11. //check for duplicate
  12. $tmp = getMetaValue($metaKey);
  13. if ($tmp) {
  14.         return -1; //key exist, do nothing
  15. } else {
  16.         $query="INSERT INTO ".$dbprefix."config (metaKey, metaValue)
  17.         VALUES (’$metaKey’,'$metaValue’) "; // insert data
  18.         $result = mysql_query($query);
  19.         $tmp=mysql_affected_rows($db)."<p>";
  20.         if ($tmp) {
  21.                 return 1;
  22.         } else {
  23.         return 0;
  24. }
  25.  
  26. } //end ELSE-IF
  27. } //end of createMetaKey

Reading a config variable

I believe the code is self explanatory. I use plain vanilla db access code. With the LIMIT clause I only read 1 record. Although this is an extra precaution, I take care of this under ‘creating new config variable’. You need to make sure the variable $metakey is wrapped in inverted commas.

  1. FUNCTION getMetaValue($metaKey)
  2. {
  3. /*
  4. Reads config info from db
  5. input :
  6.         metaKey
  7. Output :
  8.         metaValue if key is found, 0 otherwise
  9. */
  10. global $dbprefix,$db;
  11. $query = "SELECT * FROM ".$dbprefix."config WHERE metaKey=’$metaKey’ LIMIT 1";
  12. $result = mysql_query($query);
  13. $numOfRecs=mysql_numrows($result);
  14. if ($numOfRecs) {
  15.         $metaValue = mysql_result($result,0,"metaValue");
  16.         return $metaValue;
  17. } else {
  18.         return 0;
  19. }
  20. } //end of getMetaValue

Changing the value of a config variable

  1. FUNCTION setMetaValue($metaKey, $metaValue)
  2. {
  3. /*
  4. Sets config info in the db
  5. input :
  6.         metaKey, metaValue
  7. Output:
  8.         1 if success, 0 otherwise
  9. */
  10. global $dbprefix,$db;
  11. $query="UPDATE ".$dbprefix."config SET
  12. metaValue=$metaValue
  13. WHERE metaKey=’$metaKey’";
  14. //echo "query=$query : recs=$numOfRecs<br>";
  15. $result = mysql_query($query);
  16. $tmp=mysql_affected_rows($db)."<p>";
  17. if ($tmp) {
  18.         return 1;
  19. } else {
  20.         return 0;
  21. }
  22. //echo "result=$tmp<br>";
  23. } //end of setMetaValue

Here’s a sample test file

This file first creates a key named ‘version’ with a default value ‘3.2′. Then value is changed to ‘3.3′ and is read and echoed to screen. This uses two include files. First one being database config file. Read here for more info.

  1. <?php
  2. require_once("inc_dbaccess.php");
  3. require_once("inc_functions.php");
  4.  
  5. echo "<h1>Testing config manager</h1>";
  6.  
  7. echo "<h2>Creating</h2>";
  8. $m_key = ‘version’;
  9. $m_value = ‘3.2′;
  10.  
  11. echo "key=$m_key : value=$m_value (value is optional) <br>";
  12. $tmp = createMetaKey($m_key, $m_value);
  13. switch($tmp){
  14. case -1 :
  15.         echo "key already exist";
  16.         break;
  17. case 0 :
  18.         echo "db write error";
  19.         break;
  20. case 1 :
  21.         echo "key created";
  22.         break;
  23.  
  24. } //end SWITCH
  25.  
  26. echo "<h2>Setting</h2>";
  27. $m_key = ‘version’;
  28. $m_value = ‘3.3′;
  29.  
  30. echo "key=$m_key : NEW value=$m_value <br>";
  31. $tmp = setMetaValue($m_key, $m_value);
  32.  
  33. if ($tmp) {
  34.         echo "key updated succussfully";
  35. } else {
  36.         echo "key update failed";
  37.         exit;
  38. }
  39.  
  40. echo "<h2>Reading</h2>";
  41. $m_key = ‘version’;
  42. $tmp = getMetaValue($m_key);
  43. if ($tmp) {
  44.         echo "key=’$m_key’ : value= ".$tmp;
  45. } else {
  46.         echo "Wrong key.";
  47.         exit;
  48. }
  49. ?>

Conclusion

The code can be further optimized, eg: doing away with the ‘$tmp’ variable, but then again the objective of keeping that is purely to do with usability.

I keep these functions under a file named ‘inc_functions.php’ and include it in all files, as below:

  1. <?php
  2. require_once("inc_functions.php");
  3. ?>

There also times where you do not want to use a database to save configuration information. XML would be the next best option. Let’s see how.

Downloads

SQL file, PHP function library and Test file

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
  • BlinkList
  • Furl
  • Reddit
  • Technorati
  • Fleck
  • YahooMyWeb
  • Netscape
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists
Rate this article (166 views)
1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5 out of 5)
Loading ... Loading ...
Print This Post Print This Post   Email This Post Email This Post

Got something to say?