<?php
// For each flag, assign a power of two
// This makes a mask with a single bit turned on
$male = 1;
$bald = 2;
$tall = 4;
$funny = 8;
$fictitious = 16;
// To set flags, use OR
// Init John to male:
$john = $male;
// Set John to tall and fictitious
$john = $john | $tall | $fictitious;
// or $john |= $tall | $fictitious;
// To check if John is tall, use AND
if ( $john & $tall ) echo "You tall!
";
if ( ! ($john & $funny) ) echo "You not funny!
";
// or if ( ($john & $tall) == $tall )
// because since $tall only has one bit set to 1,
// something & $tall is either 0 or $tall
// but comparing to zero is faster
// than checking for equality
// To flip tall, use XOR
$john = $john ^ $tall;
// or $john ^= $tall;
$not = ( $john & $tall ) ? "" : "not ";
echo "You ".$not."tall...
";
// To unset tall, use & with the complement
$john = $john & (~ $tall);
$not = ( $john & $tall ) ? "" : "not ";
echo "You ".$not."tall, dude.
";
// To invert all flags, use NOT (~):
$antijohn = ~ $john;
$not = ( $antijohn & $funny ) ? "" : "not ";
echo "You ".$not."funny, antijohn.
";
<?php
class Permissions {
const ADD_CONTENT = 0x1;
const ADD_OWN_CONTENT = 0x2;
const EDIT_CONTENT = 0x4;
const EDIT_OWN_CONTENT = 0x8;
const DELETE_CONTENT = 0x10;
const DELETE_OWN_CONTENT = 0x20;
const ADD_COMMENT = 0x40;
const VIEW_COMMENT = 0x80;
/*
define("f0", 0x1); // 2^0
define("f1", 0x2); // 2^1
define("f2", 0x4); // 2^2
define("f3", 0x8); // 2^3
define("f4", 0x10); // 2^4
define("f5", 0x20); // 2^5
// ...
define("f20", 0x1000000); // 2^20
define("f21", 0x2000000); // 2^21
define("f22", 0x4000000); // 2^22
define("f23", 0x8000000); // 2^23
define("f24", 0x10000000); // 2^24
// ... up to 2^31
*/
}
function hasPermission($permissionToCheck, $userPermissions) {
return $permissionToCheck & $userPermissions;
}
//Give the user some permissions
$myPermissions = Permissions::ADD_CONTENT | Permissions::EDIT_CONTENT | Permissions::VIEW_COMMENT;
//Can the user add content?
if (hasPermission(Permissions::ADD_CONTENT, $myPermissions)) echo 'User can add contnet';
else echo 'User cannot add content';
echo '<br />';
if (hasPermission(Permissions::EDIT_CONTENT, $myPermissions)) echo 'User can edit contnet';
else echo 'User cannot edit content';
echo '<br />';
if (hasPermission(Permissions::DELETE_CONTENT, $myPermissions)) echo 'User can delete contnet';
else echo 'User cannot delete content';
echo '<br />';
//Revoke a permission:
$myPermissions &= ~Permissions::ADD_CONTENT;
//This should now be false
if (hasPermission(Permissions::ADD_CONTENT, $myPermissions)) echo 'User can add contnet';
else echo 'User cannot add content';
//Add a new permission:
$myPermissions |= Permissions::DELETE_OWN_CONTENT;
Initially, I found bitmasking to be a confusing concept and found no use for it. So I've whipped up this code snippet in case anyone else is confused:
<?php
// The various details a vehicle can have
$hasFourWheels = 1;
$hasTwoWheels = 2;
$hasDoors = 4;
$hasRedColour = 8;
$bike = $hasTwoWheels;
$golfBuggy = $hasFourWheels;
$ford = $hasFourWheels | $hasDoors;
$ferrari = $hasFourWheels | $hasDoors | $hasRedColour;
$isBike = $hasFourWheels & $bike; # False, because $bike doens't have four wheels
$isGolfBuggy = $hasFourWheels & $golfBuggy; # True, because $golfBuggy has four wheels
$isFord = $hasFourWheels & $ford; # True, because $ford $hasFourWheels
?>
And you can apply this to a lot of things, for example, security:
<?php
// Security permissions:
$writePost = 1;
$readPost = 2;
$deletePost = 4;
$addUser = 8;
$deleteUser = 16;
// User groups:
$administrator = $writePost | $readPosts | $deletePosts | $addUser | $deleteUser;
$moderator = $readPost | $deletePost | $deleteUser;
$writer = $writePost | $readPost;
$guest = $readPost;
// function to check for permission
function checkPermission($user, $permission) {
if($user & $permission) {
return true;
} else {
return false;
}
}
// Now we apply all of this!
if(checkPermission($administrator, $deleteUser)) {
deleteUser("Some User"); # This is executed because $administrator can $deleteUser
}
?>