哪种数据类型适合存储这种情况?

时间:2011-04-14 15:42:04

标签: php javascript types

例如,我有一个用户,并且用户具有不同的用户权限,例如,用户可以拥有

-create file
-read file
-update file
-delete file

4权限,我可以使用4 BOOL来查找用户权限,但如果用户有更多权利,我需要创建越来越多的BOOL来存储权限。我不认为这是个好主意。我想为此得到一个长整数...例如,用户可以做所有的东西是1111。 创建文件为1000,读取文件为100,更新为10,删除为1.因此,如果用户只读取文件权限为0100。

有没有更好的想法?谢谢。

2 个答案:

答案 0 :(得分:3)

我建议在二进制状态字符串中转换特权(权限),然后将其作为长整数或十六进制字符串存储在数据库中(VARCHAR;用于存储大量权限)。

实施例

$privileges_list = array(
  0 => 'create_file',
  1 => 'read_file',
  2 => 'update_file',
  3 => 'delete_file',
  4 => 'create_pool',
  5 => 'vote_in_pool',
  6 => 'create_gallery',
  7 => 'upload_images',
  8 => 'view_statistics'
);

因此,如果您要为用户设置create fileupdate fileview statistics权限,只需将1放在字符串(0,2,8)中的适当位置,将0放置在其余位置它们

$binary_string = "100000101";

此字符串中的最后一个字符是位置0,首先是位置8。

现在您可以将此字符串转换为整数(261)或十六进制数字(105),并将其作为该用户的特权集(我更喜欢十六进制)放入数据库。

要将此值转换回特权列表,您可以使用类似这样的内容

function hexvalue2privileges($hexvalue, $plist) {
  $res = array(); $res_assoc = array();
  for ($i = strlen($hexvalue) - 1; $i >= 0; $i--) {
    $bin = str_pad(decbin(hexdec(substr($hexvalue, $i, 1))), 4, '0', STR_PAD_LEFT);
    $bin_array = array_reverse(str_split($bin, 1));
    foreach ($bin_array as $bitstate) $res[] = $bitstate == '1' ? true : false;
    }
  foreach ($plist as $key => $id) {
    $res_assoc[$id] = $res[$key];
    }
  return $res_assoc;
  }

并调用此函数

print_r(hexvalue2privileges('105', $privileges_list));

输出

Array
(
    [create_file] => 1      // true
    [read_file] =>          // false
    [update_file] => 1      // true
    [delete_file] =>        // false
    [create_pool] =>        // false
    [vote_in_pool] =>       // false
    [create_gallery] =>     // false
    [upload_images] =>      // false
    [view_statistics] => 1  // true
)

对于每个十六进制字符,您可以存储4个权限,以便使用此公式计算所需字符数

$chars_needed = floor((count($privileges_list)-1) / 4) + 1; // result 3

获取二进制字符串的总长度

$binary_length = $chars_needed * 4; // result 12

修改权限设置长度

$binary_string = "100000101";
$binary_string = str_pad($binary_string, $binary_length, '0', STR_PAD_LEFT);
// result '000100000101'

将$ binary_string转换为十六进制

$binary_string = "000100000101";

$hexvalue = "";
$groups = str_split($binary_string, 4);
foreach ($groups as $group) $hexvalue .= dechex(bindec($group));

// result $hexvalue='105'   (1=0001, 0=0000, 5=0101)   

此外,您可以通过为每个组(管理员,版主,访客,贵宾等)创建权限集来创建权限组并将其分配给用户。

希望这有帮助

答案 1 :(得分:1)

使用[flags CHAR(10) default '0000000000'] 无论何时需要任何数字,都可以像

一样使用它

第一位数 - 新增 第二位数 - 编辑等。

在存储时,您只需更改该位并存储如此1100000000.就是这样。