提高设置/权限这个PHP位域类? [英] Improve this PHP bitfield class for settings/permissions?

查看:198
本文介绍了提高设置/权限这个PHP位域类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图找出现在使用位掩码在PHP或位域很长一段时间我为不同的用户设置和权限不同应用领域的最佳途径。到目前为止,我来了最远的是从堆栈溢出贡献的svens类
后的 位掩码在PHP的设置? 的。我已经略低于修改它,改变它使用类常量,而不是定义并确保GET方法是唯一通过一个int。我也有一些样本code测试下面的类的功能。

我要寻找任何建议/ code,以改善这个类更是这样它可以在我的应用程序可用于设置和在某些情况下用户权限。

回答注释低于mcrumley

<罢工>的另外,我有一个关于我的常量的编号问题。在其他类和code样品对于这种类型,将具有在二,然而权力上市的事情,似乎工作一样,据我可以告诉我就算我的编号1,2,3,4的常量, 5,6,而不是1,2,4,8,16,等于是可以有人还明确,如果我要改变我的常量?


一些想法......我真的想找出一个办法,所以很容易与其他班级使用扩展此类。比方说,我有一个用户类和的消息类。无论是用户的消息类将扩展这个类,并能使用位掩码为他们设置/权限(沿与其他类以后)。因此,也许当前类的常量应该改变,使他们能够在或其他一些选项,通过?我真的宁可不要定义(定义('PERM_READ',1);)在网站/脚本的其他部分,并想保持它有点封装,而灵活的为好;我打开思路。我想就像我说的与多个其他类设置或权限,以此来进行稳固和灵活。可能应该使用某种阵列的?从上面链接我的previous问题@Svens张贴着评论执行一些AUTOMAGIC getter / setter方法​​或ArrayAccess接口额外awesomne​​ss - svens吗?你怎么看待这样的事情,以及

包含示例源$ C ​​$ C,如果可能的话,请。

 &LT; PHP类位域{    常量PERM_READ = 0;
    常量PERM_WRITE = 1;
    常量PERM_ADMIN = 2;
    常量PERM_ADMIN2 = 3;
    常量PERM_ADMIN3 = 4;    私人$价值;    公共函数__construct($值= 0){
        $这个 - &GT;价值= $价值;
    }    公共职能的getValue(){
        返回$这个 - &GT;价值;
    }    公共职能的get($ N){
        如果(is_int($ N)){
            返回($这个 - &GT;值及(1 LT;&LT; $ N))!= 0;
        }其他{
            返回0;
        }
    }    公共功能集($ N,$新= TRUE){
        $这个 - &GT;值=($这个 - &GT;值放大器;〜(1 <<;&LT; $ N))| ($最新及LT;&LT; $ N);
    }    公共职能清晰($ N){
        $这个 - &GT;设置($ N,FALSE);
    }
}
?&GT;

使用示例...

 &LT; PHP
    $ user_permissions = 0; //此值将来自MySQL或会话
    $ BF =新位域($ user_permissions);    //开启这些权限上/真
    $ BF-&GT;设置($ BF :: PERM_READ);
    $ BF-&GT;设置($ BF :: PERM_WRITE);
    $ BF-&GT;设置($ BF :: PERM_ADMIN);
    $ BF-&GT;设置($ BF :: PERM_ADMIN2);
    $ BF-&GT;设置($ BF :: PERM_ADMIN3);    //开启权限PERM_ADMIN2为关闭/假
    $ BF-&GT;清($ BF :: PERM_ADMIN2); //设置$ BF :: PERM_ADMIN2位为假    //获取总位值
    $ user_permissions = $ BF-&GT;的getValue();    呼应'&LT; BR&GT;位掩码值='$ user_permissions。 '&LT; BR&GT;测试值开/关基于该位掩码值&LT; BR&GT;' ;    //检查许可PERM_READ是/真
    如果($ BF-&GT;获得($ BF :: PERM_READ)){
        //可以读
        呼应可以读的是针对&lt; BR&GT;';
    }    如果($ BF-&GT;获得($ BF :: PERM_WRITE)){
        //可以写
        呼应可以写的是针对&lt; BR&GT;';
    }    如果($ BF-&GT;获得($ BF :: PERM_ADMIN)){
        //为admin
        回音管理员是针对&lt; BR&GT;';
    }    如果($ BF-&GT;获得($ BF :: PERM_ADMIN2)){
        //为admin 2
        回音管理员2是针对&lt; BR&GT;';
    }    如果($ BF-&GT;获得($ BF :: PERM_ADMIN3)){
        //为admin 3
        回音管理员3是针对&lt; BR&GT;';
    }
?&GT;


解决方案

其他有助于进一步解释这样做的位掩码位,所以我会集中精力


  

我喜欢使它更加的想法
  可扩展的/通用的,所以不同
  类可以扩展这一点,并用它来
  不同的部分,我只是不知道
  如何做到这一点呢。


从@Charles后你的评论。

正如查尔斯所说的那样,你可以通过提取功能集成到一个抽象类,并把实际的设置(在这种情况下,权限)到派生具体类重复使用您的位掩码类的功能。

例如:

 &LT; PHP抽象类位域{    私人$价值;    公共函数__construct($值= 0){
        $这个 - &GT;价值= $价值;
    }    公共职能的getValue(){
        返回$这个 - &GT;价值;
    }    公共职能的get($ N){
        如果(is_int($ N)){
            返回($这个 - &GT;值及(1 LT;&LT; $ N))!= 0;
        }其他{
            返回0;
        }
    }    公共功能集($ N,$新= TRUE){
        $这个 - &GT;值=($这个 - &GT;值放大器;〜(1 <<;&LT; $ N))| ($最新及LT;&LT; $ N);
    }    公共职能清晰($ N){
        $这个 - &GT;设置($ N,FALSE);
    }
}类UserPermissions_BitField位域扩展
{
    常量PERM_READ = 0;
    常量PERM_WRITE = 1;
    常量PERM_ADMIN = 2;
    常量PERM_ADMIN2 = 3;
    常量PERM_ADMIN3 = 4;
}类UserPrivacySettings_BitField位域扩展
{
    常量PRIVACY_TOTAL = 0;
    常量PRIVACY_EMAIL = 1;
    常量PRIVACY_NAME = 2;
    常量PRIVACY_ADDRESS = 3;
    常量PRIVACY_PHONE = 4;
}

然后使用简单变为:

 &LT; PHP
$ user_permissions = 0; //此值将来自MySQL或会话
$ BF =新UserPermissions_BitField($ user_permissions);//把这些权限上/真
$ BF-&GT;设置($ BF :: PERM_READ);
$ BF-&GT;设置($ BF :: PERM_WRITE);
$ BF-&GT;设置($ BF :: PERM_ADMIN);
$ BF-&GT;设置($ BF :: PERM_ADMIN2);
$ BF-&GT;设置($ BF :: PERM_ADMIN3);

和设置隐私设置,你只需实例化一个新UserPrivacySettings_BitField对象,并使用它。

此方式,您可以根据您的应用程序通过定义一套重新present你的选择常量需要简单地创建多个不同的套位域对象。

我希望这是一些对你有用的,但如果没有,也许这将是一些使用别人谁读这一点。

I have been trying to figure out the best way to use bitmask or bitfields in PHP for a long time now for different areas of my application for different user settings and permissions. The farthest I have come so far is from a class contributed by svens in the Stack Overflow post Bitmask in PHP for settings?. I have slightly modified it below, changing it to use class constants instead of DEFINE and making sure the get method is passed an int only. I also have some sample code to test the class's functionality below.

I am looking for any suggestions/code to improve this class even more so it can be used in my application for settings and in some cases user permissions.

Answered in the comment below by mcrumley

In addition, I have a question about the numbering of my constants. In other classes and code sample for this type it will have things listed in powers of 2. However, it seems to work the same as far as I can tell even if I number my constants 1,2,3,4,5,6 instead of 1, 2, 4, 8, 16, etc. So can someone also clarify if I should change my constants?


Some ideas... I would really like to figure out a way to extend this class so it is easy to use with other classes. Let's say I have a User class and a Messages class. Both the User and Messages class will extend this class and be able to use the bitmask for their settings/permissions (along with other classes later on). So maybe the current class constants should be changed so they can be passed in or some other option? I really would rather not have to define (define('PERM_READ', 1);) in other parts of the site/script and would like to keep it somewhat encapsulated, but flexible as well; I am open to ideas. I want this to be rock solid and flexible like I said to use with multiple other classes for settings or permissions. Possibly some kind of array should be used? @Svens from my previous question linked above posted a comment with "implement some automagic getters/setters or ArrayAccess for extra awesomness. – svens" What do you think about something like that as well?

Include example source code if possible, please.

<?php

class BitField {

    const PERM_READ = 0;
    const PERM_WRITE = 1;
    const PERM_ADMIN = 2;
    const PERM_ADMIN2 = 3;
    const PERM_ADMIN3 = 4;

    private $value;

    public function __construct($value=0) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }

    public function get($n) {
        if (is_int($n)) {
            return ($this->value & (1 << $n)) != 0;
        }else{
            return 0;
        }
    }

    public function set($n, $new=true) {
        $this->value = ($this->value & ~(1 << $n)) | ($new << $n);
    }

    public function clear($n) {
        $this->set($n, false);
    }
}
?>

Example Usage...

<?php
    $user_permissions = 0; //This value will come from MySQL or Sessions
    $bf = new BitField($user_permissions);

    // Turn these permission to on/true
    $bf->set($bf::PERM_READ);
    $bf->set($bf::PERM_WRITE);
    $bf->set($bf::PERM_ADMIN);
    $bf->set($bf::PERM_ADMIN2);
    $bf->set($bf::PERM_ADMIN3);

    // Turn permission PERM_ADMIN2 to off/false
    $bf->clear($bf::PERM_ADMIN2); // sets $bf::PERM_ADMIN2 bit to false

    // Get the total bit value
    $user_permissions = $bf->getValue();

    echo '<br> Bitmask value = ' .$user_permissions. '<br>Test values on/off based off the bitmask value<br>' ;

    // Check if permission PERM_READ is on/true
    if ($bf->get($bf::PERM_READ)) {
        // can read
        echo 'can read is ON<br>';
    }

    if ($bf->get($bf::PERM_WRITE)) {
        // can write
        echo 'can write is ON<br>';
    }

    if ($bf->get($bf::PERM_ADMIN)) {
        // is admin
        echo 'admin is ON<br>';
    }

    if ($bf->get($bf::PERM_ADMIN2)) {
        // is admin 2
        echo 'admin 2 is ON<br>';
    }

    if ($bf->get($bf::PERM_ADMIN3)) {
        // is admin 3
        echo 'admin 3 is ON<br>';
    }
?>

解决方案

Others have helped with further explaining the bit masking bit of this, so I'll concentrate on

"I do like the idea of making it more extensible/generic so different classes can extend this and use it for different sections, i'm just not sure how to do it yet"

from your comment on @Charles' post.

As Charles rightly said, you can re-use the functionality of your Bitmask class by extracting the functionality into an abstract class, and putting the actual "settings" (in this case permissions) into derived concrete classes.

For example:

<?php

abstract class BitField {

    private $value;

    public function __construct($value=0) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }

    public function get($n) {
        if (is_int($n)) {
            return ($this->value & (1 << $n)) != 0;
        }else{
            return 0;
        }
    }

    public function set($n, $new=true) {
        $this->value = ($this->value & ~(1 << $n)) | ($new << $n);
    }

    public function clear($n) {
        $this->set($n, false);
    }
}

class UserPermissions_BitField extends BitField
{
    const PERM_READ = 0;
    const PERM_WRITE = 1;
    const PERM_ADMIN = 2;
    const PERM_ADMIN2 = 3;
    const PERM_ADMIN3 = 4;
}

class UserPrivacySettings_BitField extends BitField
{
    const PRIVACY_TOTAL = 0;
    const PRIVACY_EMAIL = 1;
    const PRIVACY_NAME = 2;
    const PRIVACY_ADDRESS = 3;
    const PRIVACY_PHONE = 4;
}

And then usage simply becomes:

<?php
$user_permissions = 0; //This value will come from MySQL or Sessions
$bf = new UserPermissions_BitField($user_permissions); 

// turn these permission to on/true
$bf->set($bf::PERM_READ);
$bf->set($bf::PERM_WRITE);
$bf->set($bf::PERM_ADMIN);
$bf->set($bf::PERM_ADMIN2);
$bf->set($bf::PERM_ADMIN3);

And to set privacy settings, you just instantiate a new UserPrivacySettings_BitField object and use that instead.

This way, you can create as many different sets of BitField objects as your application requires simply by defining a set of constants that represent your options.

I hope this is of some use to you, but if not, perhaps it will be of some use to someone else who reads this.

这篇关于提高设置/权限这个PHP位域类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆