Saving configuration information using key value pairs

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.

CREATE TABLE `sls_config` (
  `metaId` int(11) NOT NULL auto_increment,
  `metaKey` varchar(50) NOT NULL,
  `metaValue` varchar(50) NOT NULL,
  KEY `metaId` (`metaId`)
) 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.

FUNCTION createMetaKey($metaKey, $metaValue=0)
{
/*
Create a new key/value pair. If metaValue is not provided default = 0
input :
	metaKey, metaValue
Output:
	1 if success, -1 if duplicate found, 0 db write error
*/
global $dbprefix,$db;
//check for duplicate
$tmp = getMetaValue($metaKey);
if ($tmp) {
	return -1; //key exist, do nothing
} else {
	$query="INSERT INTO ".$dbprefix."config (metaKey, metaValue)
	VALUES ('$metaKey','$metaValue') "; // insert data
	$result = mysql_query($query);
	$tmp=mysql_affected_rows($db)."<p>";
	if ($tmp) {
		return 1;
	} else {
	return 0;
}

} //end ELSE-IF
} //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.

FUNCTION getMetaValue($metaKey)
{
/*
Reads config info from db
input :
	metaKey
Output :
	metaValue if key is found, 0 otherwise
*/
global $dbprefix,$db;
$query = "SELECT * FROM ".$dbprefix."config WHERE metaKey='$metaKey' LIMIT 1";
$result = mysql_query($query);
$numOfRecs=mysql_numrows($result);
if ($numOfRecs) {
	$metaValue = mysql_result($result,0,"metaValue");
	return $metaValue;
} else {
	return 0;
}
} //end of getMetaValue

Changing the value of a config variable

FUNCTION setMetaValue($metaKey, $metaValue)
{
/*
Sets config info in the db
input :
	metaKey, metaValue
Output:
	1 if success, 0 otherwise
*/
global $dbprefix,$db;
$query="UPDATE ".$dbprefix."config SET
metaValue=$metaValue
WHERE metaKey='$metaKey'";
//echo "query=$query : recs=$numOfRecs<br>";
$result = mysql_query($query);
$tmp=mysql_affected_rows($db)."<p>";
if ($tmp) {
	return 1;
} else {
	return 0;
}
//echo "result=$tmp<br>";
} //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.

<?php
require_once("inc_dbaccess.php");
require_once("inc_functions.php");

echo "<h1>Testing config manager</h1>";

echo "<h2>Creating</h2>";
$m_key = 'version';
$m_value = '3.2';

echo "key=$m_key : value=$m_value (value is optional) <br>";
$tmp = createMetaKey($m_key, $m_value);
switch($tmp){
case -1 :
	echo "key already exist";
	break;
case 0 :
	echo "db write error";
	break;
case 1 :
	echo "key created";
	break;

} //end SWITCH

echo "<h2>Setting</h2>";
$m_key = 'version';
$m_value = '3.3';

echo "key=$m_key : NEW value=$m_value <br>";
$tmp = setMetaValue($m_key, $m_value);

if ($tmp) {
	echo "key updated succussfully";
} else {
	echo "key update failed";
	exit;
}

echo "<h2>Reading</h2>";
$m_key = 'version';
$tmp = getMetaValue($m_key);
if ($tmp) {
	echo "key='$m_key' : value= ".$tmp;
} else {
	echo "Wrong key.";
	exit;
}
?>

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:

<?php
require_once("inc_functions.php");
?>

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

3 thoughts on “Saving configuration information using key value pairs

  1. Hi can you also show how to use XML for the same purpose please. I am still not clear about XML under PHP.

    Thanks

  2. Cool idea indeed. Saves disk space, I used a text file for the same purpose. But things like file locks etc… made think of a better way to handle config info. You showed the perfect solution.

    Thanks for sharing.

Leave a Reply

Your email address will not be published. Required fields are marked *