views:

187

answers:

7

What is the best approach to storing a group of global settings for a custom PHP application? I am working on a personal project (first major one really), and need a method of storing key-value pairs for recording overall settings for the application.

Things to store as...

  • Website's Global Name.
  • Theme (just a variable, or path to theme)
  • etc

Should I just keep them in one table? If so what is the best way to query them from a boostrap? Besides doing a single query for each desired setting.


UPDATE: Yes a .ini or parsing an include file would be nice, and I know how to do it that way. But I wanted to know what would be the best approach to storing them in MySQL with everything else.


UPDATE2: The reason I ask this also is I plan for a lot of these settings to be changeable through the Administrator interface. So if you were to change the Title of the site, it would be updated right away, which I figured would be best to do through SQL, thus needing setting inside the DB.

+6  A: 

Have you thought about putting them in a .php file and including it on the pages you need to use them? Give the variables a unique name so avoid naming conflicts.

Since you'll be using them repeatedly in your PHP application, this would be most ideal. This also avoids the need to make database calls if you were to store them in a database.

AppSettings.php

<?php
$_SITENAME_ = 'MyWebsite';
$_THEME_ = 'Theme/Path';
?>

UPDATE:

I assume you want these settings to be editable via a web page and don't want multiple DB Queries since these settings will change, but not too often?

One approach I personally took was to serialize the AppSettings table and store it in a XML file. Of course, every time the table is updated, the table would be reserialized and stored in the XML file. Then I created a separate class that parses the XML file and returns the specific values I needed.

Baddie
Title wasn't a great example, but you can assume that the bootstrap will be handling some cache functions for things like that.
Urda
Hmmm I like the XML idea... And yes these would be changable from a UI
Urda
So perhaps a system where data is updated in the Database, which can trigger a rebuild of the local parse file?
Urda
@Urda - Yeah. The "trigger doesn't have to be via SQL, you can have PHP do it right after it updates the database.
Baddie
+2  A: 

We just use

$siteConfig['db_name'] = 'database1';
$siteConfig['site_name'] = 'Stackoverflow';

In a included php file. Putting the values in a array helps with name conflicts.

nullptr
+2  A: 

i understand you want to keep things in a mysql table, however, that likely means storing required configuration in multiple places. for example, i'm sure you'll want the database server and name stored in a string somewhere. that means putting those in an include or .ini file since you can't read them from a database (how can you connect to the database without knowing those things). so, you'd be keeping the db connection info in an include or .ini file and the rest of the settings in the database? that works, i suppose, but i like to keep all of the settings in one file (config.php or application.ini or whatever). it makes it easier to maintain imo.

-don

Don Dickinson
+3  A: 

For a single, small, simple site, I'd just put config in a PHP file. Keep it simple. PHP probably doesn't parse anything faster than it parses PHP. If you use APC, the compiled bytecode is even cached -- although the bytecode is then re-executed for every request. For a small config file, this bytecode execution should take very little time; for a very large file, it might take a bit longer.

For high-traffic sites with large configs, caching your config data in APC (e.g. as a single array) is a good idea -- at the very least, you save the overhead of actually executing the statements in your config.php file. Notably, facebook does this. When you're serving many requests per second, hitting the disk to read a config file (using parse_ini_file, an XML parser, etc.) on every request is out of the question.

For my current project, we host many sites, each with their own config. Each site had both a database and a config file; however, making sure you're always using the right config file with the right database can become a headache. Additionally, changes would require changing things in two places -- the db and the config. Forgetting one or the other always caused problems, and it happened far too frequently.

We moved the config into the database, so that you can't possibly separate a db from it's correct config, and any code changes only require updating the database. The data from the config table is also aggressively cached in APC, so we query it rarely.

So, to recap:

  1. Small site: just use a config.php file
  2. Very large site: cache in APC
  3. Multiple sites: store config in database to reduce administration overhead; cache in APC to reduce database hits
Frank Farmer
I really like this overview a lot! +1
Urda
A: 

Just got done chatting with a few people on IRC about this. I looked at how Wordpress handled this after I pulled up a SQL dump of one copy. I think I'll use this layout and rename the columns a bit. But the idea is...

option_id | option_name | option_value | autoload
int       | varchar     | longtext     | varchar
(PRIMARY) | (UNIQUE)    |              |
Urda
A: 

I generally within my index.php file set up the "required" settings so:

<?php
session_start();
ob_start();

define('BASEPATH', $_SERVER['DOCUMENT_ROOT'].'/_setUp/siteSetup/');      // CHANGE TO THE PATH OF THE SITE.
define('URIPATH', 'http://localhost/_setUp/siteSetup/');                // CHANGE TO THE URL OF THE SITE.
define ('DEBUGGER', true);                                              // CHANGE TO FALSE TO HIDE DEBUG MESSAGES
include(BASEPATH.'system/lib/config.lib.php');
?>

and within my config file:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// public

/* 
example:
    <img src="<?php echo IMG ?>my_image.jpg">
    http://localhost/public/images/
    <img src="http://localhost/public/images/my_image.jpg"&gt;
*/
define('CSS', URIPATH.'public/css/');                   // DEFINE DIR: css
define('IMG', URIPATH.'public/images/');                // DEFINE DIR: images   
define('JS', URIPATH.'public/scripts/');                // DEFINE DIR: scripts

// system
define('INC', BASEPATH.'system/includes/');             // DEFINE DIR: includes
define('LIB', BASEPATH.'system/lib/');                  // DEFINE DIR: lib
define('SQL', BASEPATH.'system/sql/');                  // DEFINE DIR: sql

if (DEBUGGER) {
    ini_set('log_errors',TRUE);
    ini_set("error_log", BASEPATH.'system/'."error_log.txt");
}
else {
    ini_set('log_errors',TRUE);
    ini_set("error_log", BASEPATH.'system/'."error_log.txt");
}

$db_info = array(
    'host' => 'localhost',
    'username' => 'root',
    'password' => 'root',
    'database' => 'my_db'
);


/*
to use:
    $db_info = unserialize(DB_INFO);
    echo $db_info['host'];
    echo $db_info['username'];
    echo $db_info['password'];
    echo $db_info['database'];
*/
define('DB_INFO', serialize($db_info));
?>
cdnicoll
A: 

A decent approach would be to fetch commonly used settings once per page, via database. Something like keeping a autoload bool field that checks whether the setting should be loaded with the page. For other, much less commonly fetched settings, you can fetch them over the air.

If you decide to cache them all instead of fetching for every page, you might want to think of a way to notify the script to reload the settings -- or you'd have to manually tell it to do so, so you wouldn't get stuck with old settings after changing some.

henasraf