Frage

Ich arbeite an einem Benutzer-Rolle / Berechtigungssystem in PHP für ein Skript.

Im Folgenden ist ein Code, der eine Bitmaske Methode für Berechtigungen verwenden, dass ich auf phpbuilder.com gefunden.

Darunter Teil eine viel einfachere Version ist w3hich ohne den Bit-Teil basicly das gleiche tun könnte.

Viele Leute haben empfohlen, mit Bit-Operatoren und solche für Einstellungen und andere Dinge in PHP, habe ich nie verstanden, warum though. Im folgenden Code ist es ANY Nutzen aus dem ersten Code anstelle den zweiten mit?

<?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.';
}
?>

Nicht-Bit-Version

<?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.';
}

?>
War es hilfreich?

Lösung

Warum nicht einfach das tun ...

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.';
}

Sie können auch viele beliebige Kombinationen von Berechtigungen erstellen, wenn Sie Bits verwenden ...

$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

Andere Tipps

Die erste ermöglicht es den Menschen viele Berechtigungen zu haben - Lese- / Add / Update zum Beispiel. Das zweite Beispiel, der Benutzer hat nur PERMISSION_UPDATE.

Bitwise Werke Prüfung von Bits für Wahrheitswerte testen.

Zum Beispiel kann die Binärfolge 10010 einen Benutzer mit PERMISSION_DELETE und PERMISSION_READ identifizieren würde (das Bit PERMISSION_READ Identifizierung ist die Säule für 2, das Bit PERMISSION_DELETE Identifizierung ist die Spalte 16), 10010 in binär 18 in dezimalem (16 + 2 = 18). Ihr zweites Codebeispiel erlaubt Ihnen nicht, diese Art von Tests zu tun. Sie tun können, Größer-als-Stil überprüft, aber das setzt voraus, jeder mit PERMISSION_DELETE auch PERMISSION_UPDATE haben sollte, die keine gültige Annahme sein kann.

Vielleicht ist es nur, weil ich Bitmasken nicht sehr oft, aber ich, dass wie PHP in einer Sprache finden, wo die Produktivität der Entwickler und die Lesbarkeit des Codes ist wichtiger als Geschwindigkeit oder Speicherauslastung (in Grenzen, natürlich), gibt es keinen wirklichen Grund zur Verwendung bitmasking.

Warum nicht stattdessen eine Klasse, die Spuren Dinge wie Berechtigungen und eingeloggte Benutzer, und so weiter? Nennen wir es Auth. Dann, wenn Sie überprüfen möchten, dass ein Benutzer eine Berechtigung hat, können Sie eine Methode HasPermission erstellen. z. B.

if(Auth::logged_in() && Auth::currentUser()->hasPermission('read'))
    //user can read

dann, wenn Sie wollen prüfen, ob sie eine Kombination von Berechtigungen verfügen:

if(Auth::logged_in() && Auth::currentUser()->hasAllPermissions('read', 'write'))
    //user can read, and write

oder wenn Sie wollen prüfen, ob sie irgendeine eine bestimmte Gruppe von Berechtigungen verfügen:

if(Auth::logged_in() && Auth::currentUser()->hasAnyPermissions('read', 'write'))
    //user can read, or write

Natürlich kann es keine schlechte Idee sein Konstanten zu definieren, wie PERMISSION_READ, die Sie gerade definieren können die Zeichenfolge ‚lesen‘ zu sein, und so weiter.

ich diesen Ansatz einfacher finden als Bitmasken zu lesen, weil die Methodennamen Ihnen genau sagen, was es ist, die Sie suchen.

Bearbeiten : die Frage rereading, es sieht aus wie die Berechtigungen des Benutzers zurück aus Ihrer Datenbank in einem Bitfeld kommen. Wenn das der Fall ist, sind Sie gehen zu müssen Bitoperatoren verwenden. Ein Benutzer, der die Berechtigung in der Datenbank ist, ist 5 hat PERMISSION_READ und PERMISSION_DENIED weil (PERMISSION_READ & 5) != 0 und (PERMISSION_DENIED & 5) != 0. Er würde nicht PERMISSION_ADD haben, weil (PERMISSION_ADD & 5) == 0

Ist das sinnvoll? Die ganze Komplex Material in Ihrem bitweise Beispiel sieht nicht erforderlich.


Wenn Sie nicht vollständig bitweise Operationen verstehen, dann sie nicht verwenden. Es wird nur eine Menge Kopfschmerzen führen. Wenn Sie mit ihnen vertraut sind, sie dann verwenden, wenn Sie das Gefühl, sie angemessen sind. Sie (oder wer auch immer das bitweise Code geschrieben hat) scheint nicht vollständig bitweise Operationen zu erfassen. Es gibt mehrere Probleme mit sich, wie die Tatsache, dass die pow() Funktion verwendet wird, die jede Art von Leistungsvorteil zunichte machen würde. (Statt pow(2, $n), sollten Sie die bitweise 1 << $n verwenden, zum Beispiel.)

sagte, dass die beiden Teile des Codes scheinen nicht die gleichen Dinge zu tun.

Versuchen Sie es mit, was in der bit.class.php ist unter http://code.google.com/p/samstyle-php-framework/source/browse/trunk/class/bit.class.php

Überprüfen gegen ein bestimmtes Bit:

<?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
}

?>

Und zum Ein- und Ausschalten:

<?php

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

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

?>

Problem dafür ist, wenn PERMISSION_READ eine Maske selbst

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

dann für 0101 - $ rightWeHave 0011 - $ rightWeRequire

es Zugriff gewährt wird, die wir wahrscheinlich nicht wollen, so sollte es sein

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

so jetzt

0101 0011

Ergebnis

0001 so Zugang nicht gewährt, weil es nicht zu 0011 gleich

aber für

1101 0101

Es ist in Ordnung, da das Ergebnis 0101 ist

Script überprüft, welche Maske gesetzt worden ist in dezimal. Vielleicht hat jemand wird es brauchen:

<?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";

Output (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

Ich denke, das erste Beispiel gibt Ihnen mehr Kontrolle über genau, welche Berechtigungen ein Benutzer hat. In der zweiten haben Sie nur einen Benutzer-Ebene '; vermutlich höhere Ebene erben alle erteilten Berechtigungen auf einen niedrigeren ‚Ebene‘ Benutzer, so dass Sie nicht so feine Kontrolle haben.

Auch wenn ich das richtig verstanden habe, die Zeile

if($user_permission_level === 4)

bedeutet, dass nur Benutzer mit genau Berechtigungsstufe 4 haben Zugriff auf die Aktion - sicher würden Sie überprüfen möchten, dass Benutzer mindestens , dieses Niveau?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top