After looking at the Windows model for controlling file access, I realized I could also do that for user authorization control.
The code is pretty self explanatory, but after, you’ll find a quick rundown.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php $ADMIN = 1; $SUPERUSER = 2; $SECTION1LEADER = 4; $SECTION2LEADER = 8; $myTestUser = $SUPERUSER + $SECTION1LEADER + $SECTION2LEADER; if ($ADMIN & $myTestUser) { print 'got into admin<br />'; } if ($SECTION1LEADER & $myTestUser) { print 'section 1<br />'; } if ($SECTION2LEADER & $myTestUser) { print 'section 2<br />'; } if ($SUPERUSER & $myTestUser) { print 'got into superuser<br />'; } if ($myTestUser) { print 'is normal user.<br />'; } |
First off, the capital lettered variables are our section permission markers. These need to expand by the power of 2. This way, our bitwise operators work out well.
Next, our test user’s permissions are the summation of all the sections/permissions that they should have access to. Its important to note that $ADMIN might be better labeled as $ADMINSECTION to not give the idea of hierarchy, but just access.
Now, when checking access to the sections, we just use the bitwise and operator. See how we use just one qualifier? This is nicer coding (because of the access additions earlier) than older code ideas:
1 2 3 4 | $isADMIN = true; if ($isADMIN || || $isSuperUser || $section1LeaderAccess) { print 'section 1!'; } |
The one thing that I had to get over was the notion of a hierarchy in the actual values. Really, the hierarchy is business rule based, so the actual values do not matter. For example, if the $admin variable is less than the $superuser, I would think that it would mean the $admin was above. But technically, in our model, we could develop a $superadmin which could be 128 – without having to re-architect the whole system.
The only thing that keeps tripping me up is how to add a new permission, and then auto apply them to each user with so and so setting. So, for example, every $admin user should also have access to the new $section3leader variable. Is there a better way to code around this than doing an update query like this?
1 | update userPermission set permission = permission+128 where permission & 1 > 0 |
Seems like there would be a better way to do it… any thoughts?

I don’t know about any easier way to update the permissions of users for this kind of scheme, but I used something only vaguely similar at the University where I worked. Instead of increasing by powers of two, however, I used a bit string, with each position assigned to a specific permission. The actual permission was stored in the database as an integer, which was then turned it into an array on using
$perms = array_reverse(str_split(base_convert($intval_from_db, 10, 2))) and placed in the session.
There was a simple lookup class that looked at the permissions array which was something along the lines of:
$lookup = array(‘super’=>0,’pg2edit’=>1,’pg2view’=>2) etc. Wherever permission was needed for a specific action or to enable features on a page the lookup class was called:
if (has_permission(‘pg2edit’)) { /* some action here */ }
The lookup class simply looked at the permissions array and returned the value of (bool)$perms[$lookup[$x]]. Of course there was more stuff going on for creating the lookup array from the database, and ways to create new permissions, and the super admin permission overrode all other permissions. The application also checked, on user login, whether their permissions array was the same length as the lookup array. If it wasn’t it would add 0′s to pad it out to the proper length and save it back to the database as base_convert(implode(”,array_reverse($perms)), 2, 10).
Not that it was the most elegant, or even the most clever or original, it just worked. Now to figure out what your limitations are for explicit permissions … (btw – by the time I left there were 109 specific permissions in use on that system. o_0)