Хранение глобальных настроек сайта [PHP / MySQL] - PullRequest
4 голосов
/ 11 февраля 2010

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

Мой подход по умолчанию заключался в размещении этих предпочтений в виде пар атрибут / значение в таблице * gulp * 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'];
}

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

Ответы [ 7 ]

8 голосов
/ 11 февраля 2010

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

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 или checkbox setting_type. Он будет содержать сериализованное значение массива. В админке это значение будет отображаться как опция, поэтому админ может выбрать один из них.

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

2 голосов
/ 11 февраля 2010

Это прекрасно смотрится, как ты это делаешь.

Если вы обеспокоены тем, что ваши запросы выглядят ужасно, попробуйте немного очистить 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')

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

2 голосов
/ 11 февраля 2010

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

Вы также можете сохранить эти настройки в файле .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'];
}
1 голос
/ 11 февраля 2010

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

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

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

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

Команда:

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

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

1 голос
/ 11 февраля 2010

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

0 голосов
/ 07 октября 2015

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

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, объединить с другими таблицами для использования в более сложных запросах и т. Д.

Еще одним преимуществом этого подхода является то, что он учитывает правильные типы данных, внешние ключи и все остальные вещи, а также надлежащий дизайн базы данных для обеспечения целостности базы данных. (Просто убедитесь, что ваши внешние ключи включены при удалении SET NULL или при удалении RESTRICT, а не при удалении 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

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

0 голосов
/ 11 февраля 2010

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

включить этот класс во все вызывающие файлы.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...