Neden PHP bit / bit maskesi kullanmanız gerekir?

7 Cevap php

Ben bir komut dosyası için PHP bir kullanıcı rolü / izin sistemi üzerinde çalışıyorum.

Aşağıda phpbuilder.com bulunan izinler için bir bit maskesi yöntemi kullanarak bir koddur.

Kısmının altında bit parçası olmadan temelde aynı şeyi yapabileceğini w3hich daha basit bir versiyonudur.

Birçok kişi bit operatörleri ve PHP ayarları ve diğer şeyler için böyle kullanarak tavsiye ettim, ben neden olsa anladım hiç. Aşağıdaki kodu ANY benefit yerine ikinci 1 kodunu kullanarak var mı?

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

non-bit sürümü

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

?>

7 Cevap

Neden sadece bunu değil ...

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

Eğer bit kullanıyorsanız da izinleri keyfi kombinasyonları çok yaratabilirsiniz ...

$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

Ilk insanlar izinleri çok olmasını sağlar - örneğin, ekleme / güncelleme / okuyun. İkinci örnek, kullanıcı gelmiştir sadece PERMISSION_UPDATE.

Bit test doğruluk değerlerine bitlerini test çalışır.

Örneğin, ikili dizi 10010, belirleme bit PERMISSION_READ 2 için sütun (PERMISSION_DELETE ve PERMISSION_READ ile bir kullanıcıyı belirlemek olur bit ikili, 10010) PERMISSION_DELETE 16 için sütun tanımlayan ondalık 18'dir (16 + 2 = 18). Sizin ikinci kod örneği test bu tür yapmak için izin vermez. Sen büyüktür tarzı kontroller yapabileceğini, ama bu PERMISSION_DELETE geçerli bir varsayım olmayabilir ki, PERMISSION_UPDATE olmalıdır herkesi varsayar.

Belki çok sık bitmaskları kullanmayın, çünkü bu sadece, ama geliştirici verimliliği ve kod okunabilirliği hız ve bellek kullanımı daha önemlidir PHP gibi bir dil bulmak (sınırlar içinde, tabii ki), bitmasking kullanmak için hiçbir gerçek sebebi var .

Why not instead create a class that tracks things like permissions, and logged in users, and so on? Let's call it Auth. Then, if you want to check that a user has a permission, you can create a method HasPermission. e.g.,

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

o zaman onlar izinler bazı kombinasyonu olup olmadığını kontrol etmek istiyorsanız:

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

ya da izinleri belirli bir grubun herhangi bir sahip olup olmadığını kontrol etmek istiyorsanız:

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

Tabii ki, bu sadece böylece dize tanımlamak 'okumak' ve böyle PERMISSION_READ gibi sabitler, tanımlamak için kötü bir fikir olmayabilir.

Yöntem isimler aradığınız tam olarak ne olduğunu söyleyeyim, çünkü ben bitmasks daha okumak için bu yaklaşım daha kolay bulabilirsiniz.

Edit: kullanıcının izinleri bir saklayıcısında içinde veritabanından geri geliyor gibi soruyu rereading görünüyor. Bu durum buysa, bitsel operatörleri kullanmak zorunda olacak. Veritabanında izin olan bir kullanıcı 5, çünkü (PERMISSION_READ & 5) != 0 PERMISSION_READ ve PERMISSION_DENIED, ve (PERMISSION_DENIED & 5) != 0. O olmazdı PERMISSION_ADD, çünkü (PERMISSION_ADD & 5) == 0

Bu mantıklı mı? Lütfen bitsel örnekte tüm karmaşık şeyler gereksiz görünüyor.


If you don't fully understand bitwise operations, then don't use them. Bu sadece baş ağrısı bir sürü yol açacaktır. Onlarla rahat iseniz, uygun hissediyorum nerede, sonra bunları kullanın. Siz (veya her kim bitsel kod yazdı) tam bit işlemleri kavramak için görünmüyor. Performans yararına her türlü inkâr ederim pow() fonksiyonu kullanıldığı gerçeği gibi onunla bazı sorunlar vardır,. (Yerine pow(2, $n), örneğin, 1 << $n bit seviyesinde kullanmanız gerekir.)

Bu kod iki adet aynı şeyleri yapmak için görünmüyor, dedi.

http://code.google.com/p/samstyle-php-framework/source/browse/trunk/class/bit.class.php de bit.class.php ne olduğunu kullanmayı deneyin

Belirli bir bit karşı denetleniyor:

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

?>

Ve üzerinde ve kapatmak için:

<?php

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

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

?>

Ben ilk örnek size bir kullanıcı sahip olduğu izinlerden tam olarak ne üzerinde daha fazla denetim verir sanırım. İkincisinde sadece bir kullanıcı seviyesine 'var; muhtemelen daha yüksek düzeyleri daha düşük bir 'level' kullanıcıya verilen tüm izinleri devralır, bu nedenle böyle güzel bir kontrol yok.

Ayrıca, ben doğru anladım varsa, hat

if($user_permission_level === 4)

kesinlikle kullanıcılar at least, bu seviyede olduğunu kontrol etmek isterim - exactly izin düzeyi 4 eylem erişimi olan kullanıcılar anlamına gelir?

PERMISSION_READ bir maske kendisi ise bu sorun

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

then for 0101 - $rightWeHave 0011 - $rightWeRequire

öyle olmalıdır biz muhtemelen istemediğiniz, verilen erişim

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

şimdi için

0101 0011

sonucudur

Bu 0011 için eşit değildir çünkü 0001 bu nedenle erişimi atanmadığı

ama için

1101 0101

it is ok as the sonucudur 0101