2010-02-11 8 views
4

Может ли кто-нибудь рекомендовать наилучшую практику для хранения общих настроек сайта? Например, заголовок страницы по умолчанию, если сценарий не установлен, или количество отображаемых элементов для отображения в окне содержимого, или список миниатюр, которые система должна делать при загрузке изображения. Централизация этих значений имеет очевидное преимущество, позволяющее легко изменять предпочтения, которые могут использоваться на многих страницах.Хранение глобальных настроек сайта [PHP/MySQL]

Мой подход по умолчанию состоял в том, чтобы поместить эти предпочтения в пары атрибутов/значений в таблице * galp * Таблица EAV.

Этот стол вряд ли когда-либо станет значительным, поэтому я не слишком беспокоюсь о производительности. Остальная часть моей схемы является реляционной. Тем не менее, он делает для некоторых проклятых уродливых запросов:

$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']; 
} 

Может ли кто-нибудь предложить лучший подход?

ответ

2

Это выглядит так, как вы это делаете.

Если вы обеспокоены тем, что ваши запросы выглядят уродливыми, вы можете попробовать немного очистить свой SQL.

Вот уборщик версия запроса вы дали в вашем вопросе:

SELECT name, value FROM preferences 
WHERE name IN ('picture_sizes','num_picture_fields','server_path_to_http','picture_directory')"; 

Или, возможно, создать хранимую функцию, возвращающую значение предпочтения; например, с помощью хранимой функции, как это:

DELIMITER $$ 

CREATE FUNCTION `getPreference` (p_name VARCHAR(50)) RETURNS VARCHAR(200) 
BEGIN 
    RETURN (SELECT `value` FROM preferences WHERE `name` = p_name); 
END $$ 

DELIMITER ; 

Вы можете получить свои предпочтения с помощью запроса, как это:

SELECT getPreference('server_path_to_http') 

Вы пожертвовать немного скорости, не имея ваши предпочтения жестко закодированы (очевидно). Но если вы планируете включить «администратора сайта» для изменения настроек по умолчанию, вы должны сохранить их в базе данных.

+0

Удивительный, я люблю чистый код! – cantlin

0

Просто создайте класс конфигурации и сохраните каждое значение, которое вы хотите в переменной класса.

Включает этот класс во все файлы, которые вызывают.

Теперь вы можете получить доступ к этому классу во всех файлах и объявить глобальную функцию во всех функциях, с которыми вы можете получить доступ к классу configure.

Надеюсь, что эта помощь.

2

Я думаю, что это вполне приемлемая структура, особенно для небольших конфигураций, подобных вам.

Вы также можете сохранить эти настройки в файле .ini и позвонить по телефону parse_ini_file. Если вам нужна дополнительная гибкость, чем позволяет INI (например, вложенные массивы и т. Д.), Вы можете просто поместить их в файл .php и включить его.

Если вы все еще хотите пойти с конфигурацией в базе данных, то (учитывая, что есть только несколько строк), возможно, просто прочитайте все записи за один проход и кешируйте их.

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

Спасибо, Ник. Моя единственная забота о сохранении значений в файле заключалась в том, что это сделало бы их немного сложнее изменить через какой-то будущий интерфейс администратора. – cantlin

+0

Я также рекомендую использовать сеансы PHP и сохранять эти значения конфигурации в массиве в сеансе пользователя. Затем над этим кодом проверьте, существует ли массив, если это так, используйте его, если не запрос. Таким образом, вам не нужно запрашивать базу данных для этого EVERYTIME, когда пользователь просматривает страницу. Единственным условием является то, что измененное значение конфигурации не будет влиять, пока пользователи не войдут в систему до истечения срока их сеанса. – TravisO

+0

сделаю! Приветствия. – cantlin

1

Я думаю, что происходит с включенным файлом сэкономит вам некоторые хлопоты в дальнейшем - особенно, если вы хотите, чтобы включить массив в качестве одного из ваших переменных. Если вы планируете менять конфигурационные переменные «на лету», то, возможно, лучше их использовать, но если он останется относительно статическим, я бы порекомендовал файл «config.php»

8

В моем приложении я использую эту структуру:

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; 

Пример данные:

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 | 

хранить сериализованное значение в столбце setting_value. Я получил этот трюк из Wordpress, чтобы сохранить настройки в базе данных.

setting_options колонка используется для select, radio или checkboxsetting_type. Он будет содержать сериализованное значение массива. В admin это значение будет отображаться как параметры, поэтому администратор может выбрать один из них.

Поскольку я использую CodeIgniter, у меня есть модель для получения единственного значения от конкретного setting_key, поэтому его довольно легко использовать.

+0

Выглядит как мощное решение. Возможно, это слишком мощно для моих целей, но я обязательно буду иметь в виду, если я захочу расширить конфигурацию своего сайта. Благодаря! – cantlin

+0

Ну, это долгий путь. Я начинаю с простых, как ваш, и постепенно добавляю больше столбцов по мере необходимости, уточняю способ изменения значения и получения текущего значения. Я предлагаю вам найти свою собственную и использовать ее всякий раз, когда вы можете, поэтому вы знаете, что это слабость и сделать ее лучше. –

+0

какой вес делать? – nickf

1

Много приложений, включая, например, Wordpress, используйте сериализацию и unserialization. Он позволяет создать очень простую структуру таблиц, возможно, даже с одной записью (например, с сайтом_ид для вашего проекта).

Все ваши (многие, многие) переменные в массиве сериализуются в строку и сохраняются. Затем возвращаются и неэтериализуются обратно в структуру массива.

Pro: Вам не нужно планировать идеальные конфигурационные структуры заранее, делая много материалов ALTER TABLE.

Con: Вы не можете выполнять поиск по вашей сериализованной структуре массива с помощью SQL.

Команды:

string serialize (mixed $value ) 
mixed unserialize (string $str ) 

работает также с вашими объектами. Несериализация объекта может использовать метод __wakeup().

0

Мой подход к этой проблеме состоит в том, чтобы создать таблицу, которая представляет собой отдельный столбец для каждой переменной конфигурации, как и любой другой набор данных, и установить первичный ключ таким образом, чтобы таблица была неспособна содержать больше чем одна запись. Я делаю это путем создания первичного ключа, как перечисление только с одним возможным значением, например, так:

CREATE TABLE IF NOT EXISTS `global_config` (
    `row_limiter` enum('onlyOneRowAllowed') NOT NULL DEFAULT 'onlyOneRowAllowed',#only one possible value 
    `someconfigvar` int(10) UNSIGNED NOT NULL DEFAULT 0, 
    `someotherconfigvar` varchar(32) DEFAULT 'whatever', 
    PRIMARY KEY(`row_limiter`)#primary key on a field which only allows one possible value 
) ENGINE = InnoDB; 

INSERT IGNORE INTO `global_config`() VALUES();#to ensure our one row exists 

После того, как вы сделали эту установку, любое из значений затем может быть изменен с помощью простого заявления UPDATE, посмотрел с простым оператором SELECT, соединенным с другими таблицами, которые будут использоваться в более сложных запросах и т. д.

Другим преимуществом этого подхода является то, что он позволяет использовать правильные типы данных, внешние ключи и все другие вещи, с надлежащим дизайном базы данных для обеспечения целостности базы данных. (Просто убедитесь, что ваши внешние ключи включены DELETE SET NULL или ON DELETE RESTRICT, а не ON DELETE CASCADE).Например, допустим, что одна из вашей переменной конфигурации является идентификатором пользователя основного администратора сайта, вы можете расширить пример со следующим:

CREATE TABLE IF NOT EXISTS `global_config` (
    `row_limiter` enum('onlyOneRowAllowed') NOT NULL DEFAULT 'onlyOneRowAllowed', 
    `someconfigvar` int(10) UNSIGNED NOT NULL DEFAULT 0, 
    `someotherconfigvar` varchar(32) DEFAULT 'whatever', 
    `primary_admin_id` bigint(20) UNSIGNED NOT NULL, 
    PRIMARY KEY(`row_limiter`), 
    FOREIGN KEY(`primary_admin_id`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT ON UPDATE CASCADE 
) ENGINE = InnoDB; 

INSERT IGNORE INTO `global_config` (`primary_admin_id`) VALUES (1);#assuming your DB is set up that the initial user created is also the admin 

Это гарантирует, что вы всегда иметь действительную конфигурацию на месте, даже когда переменная конфигурации должна ссылаться на какой-либо другой объект в базе данных.

Смежные вопросы