3

PHPの人々はE_ALL、関数のおよびその他のさまざまなビットマスク定数に精通していると思いerror_reporting()ます。それらは数値定数です。例:E_ALLmeans32676E_NOTICEmeans 8。私はすべてのエラーが欲しいと言うことができますが、通知が表示されます。これはE_ALL & ~E_NOTICE、の引数として渡すことによって行いますerror_reporting()。しかし、本質的に、私はそれ32759がどちらであるかを伝えます32767 - 8

これらのビットマスクは、f(x) = 2^x関数の出力セットから値を取得し、これらの値に対して加算および減算演算を実行することで、取得するエラーを微調整できます。

フレームワークに実装する、より構成可能なアクセス制御を考えています。このために、ユーザーのビットマスクに数値を加算するのと同じ方法を設定したいのですが、問題は、これを実行する方法、要求された値と現在の値を確認する方法がわからないことです。ユーザーはfoob​​arにアクセスする権限がありますか?

そしてもう1つの問題はスケーラビリティです。私は31個の一意のビットしか持っていない可能性があり(2^32大きすぎて保守不可能な状態に達するため)、この障壁を経験する必要がある場合(現在は実際には計画されていません)、移行するのは難しいでしょうか?user.idアクセス制御についての他の考えは、彼が持っているアクセスビットの整数値とをリンクするテーブルを設定することです。

まとめると、次の2つのオプションのどちらがより良い解決策ですか?

  • ユーザーのテーブルの1つのフィールドを使用してビットマスクを格納し、必要に応じてそこから要求されたビットをフェッチします。
  • テーブルにアクセスフラグのセットを定義し、ユーザーをアクセスにリンクするリレーションテーブルを用意して、リレーショナルデータベースの素晴らしさをニーズに合わせて活用します。

私は2番目の方法について研究していましたが、どちらを使用するのが最適かわかりません。

4

2 に答える 2

0

データベースには、いくつかの異なる値を表す大きな整数を含めることはできません。フィールドごとに1つの値、これがデータ変更(または何か)の最初の法則です。

つまり、次のような2番目のテーブルが必要です。userIDフィールドとaccessbit。

userPriviliges:

  • userID、int、primary
  • 特権、int
于 2012-08-03T16:57:05.100 に答える
0

ビットマスク

ビットマスクの元々の問題は、データモデリングの規則に反することです(ここここをさらに読んで、ここで別の回答で表現されています)。4バイトの符号付き整数には、異なる値(整数で)のみが含まれる場合があり、それらを使用すると計算が困難になります。このトピックについて説明する前に、Stack Overflowについてさまざまな質問がありました。これは、bistmasksがどのように機能するかを理解するために使用しました。312 147 483 648

テストでは、ビットマスクの操作が難しいことも明らかになりました。ビット単位の演算子を理解する必要があり、移行は基本的に不可能になります。(不可能とは、最初はビットマスクを実装するのは良いことのように思えましたが、結局のところ、見返りとして得られるメリットと比較して、多額の費用がかかることがわかりました。)基本的なポータルのようなWebサイトを利用します。私はいいえを意味します。StackOverflowを利用する例として、そしてそれが持っているユニークな特権の量。私は実際に数えようとしましたが、複雑さを失いましたが、必要な量は、31の一意の値という前述の障壁をまだ超えていないとしても、はるかに近いものです。ビットマスクの意味を変更するプロジェクトの更新により、再計算が長時間必要になる可能性が非常に高く、データベースエラーが発生すると、エラーが発生しやすくなります。

正確で正確なタイミングの数値はわかりませんが、ビットマスクの使用はACLよりも遅いと感じました。データベースのサイズ、メモリ、ストレージのフットプリントを比較すると、より大きくなり、リレーショナルデータベースとインデックス作成機能を利用する機会が少なくなります。Webサイトでのユーザー権限については、他の方法を使用する場合、ビットマスクは使用できません

ビットマスクが機能するさまざまなシステム、つまりMaNGOS(私が最初にアイデアを思いついた)がありitem_template、他のさまざまなテンプレートテーブルがビットマスクを使用するフラグを定義します。しかし、肝心なのは、これらのテーブルでは、値が変更される可能性は低く、ユーザーが任意に特権を取得および失うWebサイトとは対照的に、計算は読み取り専用であるということです。

サンプルコード

define('U_NIL', 0);
define('U_EXEC', 1);
define('U_WRIT', 2);
define('U_READ', 4);

$our_perm = 7;
$req_perm = U_EXEC | U_WRIT | U_READ;
var_dump( ($our_perm & $req_perm) == $req_perm ); # Will be bool(true)

$our_perm = 3;
var_dump( ... The same thing ...); # Will be bool(false)

$our_perm = U_READ;
$req_perm = U_READ | U_WRIT;
var_dumo(...); # Will be bool(false)

$our_perm = U_READ | U_WRIT | U_EXEC;
$req_perm = U_READ;
var_dump(...); # Will be bool(true)

その他。

他のさまざまな 質問がメソッドを適切に説明しているので、コード行を割愛します。私がそれを説明することは決してできません。ビットマスクは素晴らしいようで、ビットマスクはエキゾチックなようですが、本番環境に定着させる意味はありません。

ACL

元の質問で説明されたもう1つのオプションは、リレーショナルデータベースとSQL言語を利用して、データベースにアクセス許可を設定することでした。データベースにさらに2つのテーブルを作成する必要があります。

CREATE TABLE `perm_relation` (
    `row_id` int(10) NOT NULL AUTO_INCREMENT,
    `user_id` int(10) NOT NULL,
    `perm_id` int(10) NOT NULL,
    PRIMARY KEY (`row_id`),
    UNIQUE `permission` (`user_id`, `perm_id`)
) ENGINE=InnoDB;

CREATE TABLE `permission` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `name` varchar(64) NOT NULL,
    PRIMARY KEY (`row_id`)
) ENGINE=InnoDB;

perm_relation.perm_idを指す外部キーになりpermission.id、とperm_relation.user_idの関係になりusers.idます。この後は、プログラミングロジックをどのように組み合わせるかだけが問題になります。

SELECT row_id FROM perm_relation
WHERE perm_id = (SELECT id FROM permission WHERE name = "U_SUPERADMIN")
AND user_id = CURRENT_USER_ID;

この方法を使用して、互換性の向上、実行の迅速化、移行の容易化を実現します。新しい権限を定義することと、任意のユーザーに一部を付与することの両方として、新しい権限を追加するのにほんの少しの時間しかかかりません。削除も同様に簡単で、テーブルを最適化して孤立した全体を削除するのに必要なSQLクエリはわずかです(たとえば、システムで定義された関連する権限なしに権限が付与されているユーザー)。

このシステムをPHP環境に実装しているため、この権限リストに依存する多くの機能を備えたある種の管理ページがあると想定できます。ユーザーが持っている権限でフィルタリングされたユーザーを一覧表示する例は、1つの例です。JOINこのコンテキストでは、ACLはビットマスクよりもはるかに優れています。これは、ステートメントをさらに活用できるためです。

結論は、ビットマスクとリレーショナルパターンには異なる目的があるということです。上記のMaNGOSの例では、リレーショナルテーブルはやり過ぎになりますが、ビットマスクはユーザー権限システムには多すぎて非常にかさばります。

于 2012-08-08T10:57:37.277 に答える