Это битовая маска. Это работает так: вы назначаете каждой роли прогрессивный номер, затем, когда вы хотите назначить одну роль пользователю, вы выбираете номер этой роли. Если вы хотите добавить другую роль, просто добавьте этот номер роли к исходной. Вы можете добавить столько ролей, сколько пожелаете. Хитрость в том, как вы выбираете свои числа: они являются степенями 2.
Вот пример:
Role: Editor. Value: 2^0 = 1
Role: Manager. Value: 2^1 = 2
Role: Supervisor. Value: 2^2 = 4
Role: Admin. Value: 2^3 = 8
...
Чтобы дать пользователю роль редактора, вы сохраняете 1 в базу данных,
Чтобы дать пользователю роли редактора, менеджера и администратора, вы сохраняете 1 + 2 + 8 = 11
Вы можете понять, почему это работает, если рассматривать его как массив значений 1 или 0.
|__|__|__|__|__|__|
16 8 4 2 1
Каждая роль - это 1 в соответствующем слоте. Итак, наш случай 11:
|__|__|_1|_0|_1|_1|
16 8 4 2 1
Если у вас есть битовая маска, и вы хотите знать, имеет ли пользователь определенную роль, вы используете эту операцию:
(bitmask & role_value)> = 1
Например:
(11 и 8)> = 1? да, поэтому у пользователя есть роль администратора
(11 и 4)> = 1? нет, поэтому пользователь не имеет роли супервизора
Это называется битовой маской, потому что вы делаете, чтобы «проверить, есть ли в определенной позиции 1», то есть «применить маску, которая замаскирует (установит в 0) все места, кроме тот, который вы ищете):
11 --> |__|__|_1|_0|_1|_1|
16 8 4 2 1
8 --> |__|__|_1|_0|_0|_0| (mask)
16 8 4 2 1
AND -> |__|__|_1|_0|_0|_0| Result: Yes
Надеюсь, это помогло:)