Can anybody recommend the very best practice for storing general site preferences? For instance, the default page title when the script does not set one, or the amount of featured products to show inside a content box, or a listing of thumbnail dimensions the system should make whenever a picture is submitted. Centralizing these values has got the apparent advantage of permitting someone to easily alter preferences that could be utilized on many pages.

My default approach ended up being to place these preferences as attribute/value pairs inside a *gulp* EAV table.

This table is not likely ever being of the significant size, so I am much less concerned about performance. The relaxation of my schema is relational. It will alllow for some damn ugly queries though:

$sql = "SELECT name, value FROM preferences"
.    " WHERE name = 'picture_sizes'"
.    " OR name = 'num_picture_fields'"
.    " OR name = 'server_path_to_http'"
.    " OR name = 'picture_directory'";
$query = mysql_query($sql);
if(!$query) {
    echo "Oops! ".mysql_error();
}
while($results = mysql_fetch_assoc($query)) {
    $pref[$results['name']] = $results['value'];
}

Can anybody advise a better approach?

During my application, I personally use this structure:

CREATE TABLE `general_settings` (
  `setting_key` varchar(255) NOT NULL,
  `setting_group` varchar(255) NOT NULL DEFAULT 'general',
  `setting_label` varchar(255) DEFAULT NULL,
  `setting_type` enum('text','integer','float','textarea','select','radio','checkbox') NOT NULL DEFAULT 'text',
  `setting_value` text NOT NULL,
  `setting_options` varchar(255) DEFAULT NULL,
  `setting_weight` int(11) DEFAULT '0',
  PRIMARY KEY (`setting_key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Example data:

mysql> select * from general_settings;
+-----------------------------+---------------+------------------------------+--------------+-------------------------------+---------------------------------------+----------------+
| setting_key                 | setting_group | setting_label                | setting_type | setting_value                 | setting_options                       | setting_weight |
+-----------------------------+---------------+------------------------------+--------------+-------------------------------+---------------------------------------+----------------+
| website_name                | website       | Website Name                 | text         | s:6:"DeenTV";                 | NULL                                  |              1 | 

I store a serialized value in setting_value column. I acquired this trick from wordpress method for saving configurations in database.

setting_options column can be used for any select, radio, or checkbox setting_type. It'll have a serialized array value. In admin, this value is going to be displayed like a options, so admin can pick among it.

Since I Have use CodeIgniter, I've got a model to obtain a single value in the particular setting_key, therefore it is quite simple to use.

I believe this is a perfectly acceptable structure, specifically for small quantities of configuration as if you have.

You might store these configurations within an .ini file and call parse_ini_file. If you want a little more versatility than INI enables (eg: nested arrays, etc), then you may just place them all right into a .php file and can include that.

Should you still want to choose the configuration within the database, then (considering that there's only a number of rows) possibly just read all of the records all at once and cache it.

$config = array();
$result = mysql_query("SELECT * FROM config");
while ($row = mysql_fetch_assoc($result)) {
    $config[$row['name']] = $row['value'];
}

I'd believe that choosing an incorporated file could save you some hassle further on - particularly if you ever wish to have an array among your variables. Should you intend on altering configuration variables quickly then possibly its easier to db it, but when its likely to remain relatively static I would suggest a 'config.php' file