4

一般的なサイト設定を保存するためのベスト プラクティスを推奨できる人はいますか? たとえば、スクリプトでページ タイトルが設定されていない場合のデフォルトのページ タイトル、コンテンツ ボックスに表示されるおすすめのアイテムの数、または画像がアップロードされたときにシステムが作成するサムネイル サイズのリストなどです。これらの値を一元化することには、多くのページで使用される可能性のある設定を簡単に変更できるという明らかな利点があります。

私のデフォルトのアプローチは、これらのプリファレンスを属性/値のペアとして *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'];
}

誰でもより良いアプローチを提案できますか?

4

7 に答える 7

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シリアル化された値を列に格納します。データベースに設定を保存するワードプレスの方法からこのトリックを取得しました。

setting_options列はselectradio、またはに使用されcheckbox setting_typeます。シリアル化された配列値が含まれます。管理者では、この値はオプションとして表示されるため、管理者はそのいずれかを選択できます。

私は CodeIgniter を使用しているsetting_keyので、特定の から単一の値を取得するモデルを持っているので、非常に使いやすいです。

于 2010-02-11T14:47:37.347 に答える
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'];
}
于 2010-02-11T14:35:53.437 に答える
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')

設定をハードコーディングしないと、速度が少し犠牲になります (明らかに)。ただし、「サイト管理者」がデフォルト設定を変更できるようにする場合は、それらをデータベースに保持する必要があります。

于 2010-02-11T15:05:26.157 に答える
1

インクルードされたファイルを使用すると、特に変数の1つとして配列を含めたい場合に、さらに手間が省けると思います。その場で構成変数を変更する予定がある場合は、おそらくそれをデータベース化する方がよいでしょうが、比較的静的なままにする場合は、「config.php」ファイルをお勧めします

于 2010-02-11T14:46:13.433 に答える
1

Wordpress などの多くのアプリケーションは、シリアル化と非シリアル化を利用しています。これにより、おそらく 1 つのレコードだけでも非常に単純なテーブル構造を作成できます (たとえば、プロジェクトの site_id を使用)。

配列内のすべての (多数の) 変数は、文字列にシリアル化されて格納されます。次に、フェッチしてシリアル化を解除し、配列構造に戻します。

長所: 事前に完全な構成構造を計画して、多くの ALTER TABLE を実行する必要はありません。

短所: SQL を使用してシリアライズされた配列構造を検索することはできません。

コマンド:

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

あなたのオブジェクトでも動作します。オブジェクトのシリアル化を解除するには、__wakeup() メソッドを利用できます。

于 2010-02-11T15:07:03.733 に答える
0

この問題に対する私のアプローチは、他のデータセットの場合と同じように、構成変数ごとに個別の列を持つテーブルを作成し、テーブルに複数のエントリを含めることができないように主キーを設定することです。 . これを行うには、次のように、許可される値を 1 つだけ持つ列挙型として主キーを設定します。

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 ステートメントで検索したり、他のテーブルに結合してより複雑なクエリで使用したりできます。

このアプローチのもう 1 つの利点は、適切なデータ型、外部キー、およびデータベースの整合性を確保するための適切なデータベース設計に付随するその他すべてのものを使用できることです。(外部キーを ON DELETE CASCADE ではなく ON DELETE SET NULL または ON DELETE RESTRICT にしてください)。たとえば、構成変数の 1 つがサイトの主任管理者のユーザー ID であるとします。この例を次のように拡張できます。

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

これにより、構成変数がデータベース内の他のエンティティを参照する必要がある場合でも、常に有効な構成が配置されていることが保証されます。

于 2015-10-07T15:18:45.630 に答える
0

構成クラスを作成し、必要な各値をクラスの変数に格納するだけです。

呼び出しているすべてのファイルにこのクラスを含めます。

すべてのファイルでこのクラスにアクセスできるようになり、すべての関数でグローバルを宣言することで、configure クラスにアクセスできます。

この助けを願っています。

于 2010-02-11T14:32:08.080 に答える