18

私はスクリプトのためにPHPのユーザーロール/パーミッションシステムに取り組んでいます。

以下は、phpbuilder.comで見つけた権限にビットマスクメソッドを使用したコードです。

その部分の下には、はるかに単純なバージョンがあります。w3hichは、ビット部分がなくても基本的に同じことを実行できます。

多くの人がPHPの設定などにビット演算子などを使うことを勧めていますが、その理由はわかりません。以下のコードでは、2番目のコードの代わりに最初のコードを使用することによるメリットはありますか?

<?php
/**
 * Correct the variables stored in array.
 * @param    integer    $mask Integer of the bit
 * @return    array
 */
function bitMask($mask = 0) {
    $return = array();
    while ($mask > 0) {
        for($i = 0, $n = 0; $i <= $mask; $i = 1 * pow(2, $n), $n++) {
            $end = $i;
        }
        $return[] = $end;
        $mask = $mask - $end;
    }
    sort($return);
    return $return;
}


define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD',  2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);

//run function
// this value would be pulled from a user's setting mysql table
$_ARR_permission = bitMask('5');

if(in_array(PERMISSION_READ, $_ARR_permission)) {
    echo 'Access granted.';
}else {
    echo 'Access denied.';
}
?>

非ビットバージョン

<?PHP
/*
   NON bitwise method
*/

// this value would be pulled from a user's setting mysql table
$user_permission_level = 4;

if($user_permission_level === 4) {
    echo 'Access granted.';
}else {
    echo 'Access denied.';
}

?>
4

8 に答える 8

41

なぜこれをしないのですか...

define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD',  2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);

//run function
// this value would be pulled from a user's setting mysql table
$_ARR_permission = 5;

if($_ARR_permission & PERMISSION_READ) {
    echo 'Access granted.';
}else {
    echo 'Access denied.';
}

ビットを使用する場合は、権限の任意の組み合わせを多数作成することもできます...

$read_only = PERMISSION_READ;
$read_delete = PERMISSION_READ | PERMISSION_DELETE;
$full_rights = PERMISSION_DENIED | PERMISSION_READ | PERMISSION_ADD | PERMISSION_UPDATE | PERMISSION_DELETE;

//manipulating permissions is easy...
$myrights = PERMISSION_READ;
$myrights |= PERMISSION_UPDATE;    // add Update permission to my rights
于 2009-09-04T15:55:49.253 に答える
10

1つ目は、人々が多くの権限を持つことを可能にします-たとえば、読み取り/追加/更新。2番目の例では、ユーザーはPERMISSION_UPDATE

ビット単位のテストは、ビットの真理値をテストすることによって機能します。

たとえば、バイナリシーケンスは、と(ビット識別は2の列、ビット識別は16の列)で10010ユーザーを識別し、バイナリでは10進数で18(16 + 2 = 18)になります。2番目のコードサンプルでは、​​そのようなテストを行うことはできません。スタイルチェックよりも大きいものを実行することもできますが、それは、のすべての人がを持っている必要があることを前提としています。これは有効な前提ではない可能性があります。PERMISSION_DELETEPERMISSION_READPERMISSION_READPERMISSION_DELETE10010PERMISSION_DELETEPERMISSION_UPDATE

于 2009-09-04T15:54:01.143 に答える
1

編集:質問を読み直すと、ユーザーの権限がデータベースからビットフィールドに戻ってきているようです。その場合は、ビット演算子を使用する必要があります。データベースでのアクセス許可を持つユーザーは、、、およびを5持っているためです。彼は持っていなかったでしょう、なぜならPERMISSION_READPERMISSION_DENIED(PERMISSION_READ & 5) != 0(PERMISSION_DENIED & 5) != 0PERMISSION_ADD(PERMISSION_ADD & 5) == 0

それは理にかなっていますか?ビット単位の例の複雑なものはすべて不要に見えます。


ビット演算を完全に理解していない場合は、それらを使用しないでください。 それは多くの頭痛につながるだけです。それらに慣れている場合は、適切と思われる場所で使用してください。あなた(またはビット単位のコードを書いた人)は、ビット単位の演算を完全には理解していないようです。pow()関数が使用されているという事実のように、パフォーマンス上の利点を無効にするいくつかの問題があります。(たとえば、の代わりにpow(2, $n)、ビット単位を使用する必要があります。)1 << $n

とはいえ、2つのコードは同じことをしていないようです。

于 2009-09-04T15:53:11.097 に答える
1

http://code.google.com/p/samstyle-php-framework/source/browse/trunk/class/bit.class.phpの bit.class.php にあるものを使用してみてください

特定のビットに対するチェック:

<?php

define('PERMISSION_DENIED', 1);
define('PERMISSION_READ', 2);
define('PERMISSION_ADD',  3);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 5);


if(bit::query($permission,PERMISSION_DENIED)){
echo 'Your permission is denied';
exit();
}else{
// so on
}

?>

オンとオフを切り替えるには:

<?php

$permissions = 8;
bit::toggle(&$permissions,PERMISSION_DENIED);

var_dump($permissions); // outputs int(9)

?>
于 2009-09-05T15:32:28.307 に答える
1

これの問題は、PERMISSION_READ がマスク自体である場合です。

if($ARR_permission & PERMISSION_READ) {
    echo 'Access granted.';
}else {
    echo 'Access denied.';

次に 0101 - $rightWeHave 0011 - $rightWeRequire

これはアクセス許可ですが、これはおそらく望ましくないため、そうする必要があります

if (($rightWeHave & $rightWeRequire) == $rightWeRequire) {
echo 'access granted';
}

だから今のために

0101 0011

結果は

0001 であり、0011 と等しくないため、アクセスは許可されません

しかし、

1101 0101

結果は0101なのでOK

于 2012-03-21T10:37:05.713 に答える
1

スクリプトは、どのマスクが 10 進数で設定されているかをチェックします。多分誰かがそれを必要とするでしょう:

<?php

$max = 1073741824;
$series = array(0);
$x = 1;
$input = $argv[1]; # from command line eg.'12345': php script.php 12345
$sum = 0;

# generates all bitmasks (with $max)
while ($x <= $max) {
    $series[] = $x;
    $x = $x * 2;
}

# show what bitmask has been set in '$argv[1]'
foreach ($series as $value) {
    if ($value & $input) {
        $sum += $value;
        echo "$value - SET,\n";
    } else {
        echo "$value\n";
    }
}

# sum of set masks
echo "\nSum of set masks: $sum\n\n";

出力 (php maskChecker.php 123):

0
1 - SET,
2 - SET,
4
8 - SET,
16 - SET,
32 - SET,
64 - SET,
128
256
512
1024
2048
4096
8192
(...)

Sum of set mask: 123
于 2016-06-16T09:58:24.287 に答える
0

最初の例では、ユーザーが持っている権限を正確に制御できると思います。2番目の例では、ユーザー'レベル'があります。おそらく、より高いレベルは、より低い「レベル」のユーザーに付与されたすべての権限を継承するため、そのような細かい制御はできません。

また、私が正しく理解していれば、行

if($user_permission_level === 4)

つまり、正確にアクセス許可レベル4のユーザーのみがアクションにアクセスできます。確かに、ユーザーが少なくともそのレベルを持っていることを確認する必要がありますか?

于 2009-09-04T15:53:02.813 に答える