[PHP] Using Bitwise Operators?

Chroder's picture

He has: 91 posts

Joined: Mar 2004

I was thinking of using bit fields to store user permissions in a script I'm creating for a client. It's kind of a new area for me and there doesn't seem to be too much in the documentation.

If anyone could give me a link or just explain it a little, that would be great Smiling

Chroder's picture

He has: 91 posts

Joined: Mar 2004

I think I kinda get it, but I'll still need a tutorial on how to make it practical Laughing out loud

I did this stuff in my programming class Laughing out loud But I need to know how using this stuff in PHP works...

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

I would use constants to setup a kinda key system...

Below is a fragment of a file I wrote about 2 years ago for my WAHL project (Web Admin for Half-Life). Table columns were:

id int(11) unsigned not null auto_increment
var varchar(50) not null
val blob not null
define enum('true','false') not null default 'false'

<?php
// get the WAHL settings out of the DB
$query = \"SELECT * FROM \" . _DBNAME . '.' . _DBTABLE_SETTINGS;
$result = mysql_query($query);
if (!
$result) {
    // leave commented for normal use, uncomment for debuging only
    // if query fails, an error will be reported on the main index,
    //  and the default settings will be loaded from default.cfg.php
    //Query_Error(__FILE__, __LINE__,
$query);
   
   
$config_error = \"\"
        .\"WAHL was unable to read setting from the database, check the following:\n\"
        .\"  <b>o</b> db_conn.php - make sure your DB connection info is correct\n\"
        .\"  <b>o</b> make sure you have your mySQL tables built\n\"
        .\"      check install.mysql.sql for more info\";
   
    // set some default values
    if (!@include_once('default.cfg.php')) {
        echo \"<html>\n<body>\n<pre>\n\";
        echo \"<b>Error:</b> Cannot continue\n\";
        echo \"\n\";
        echo
$config_error;
        echo \"\n\";
        echo \"\n\";
        echo \"WAHL was unable to read the default settings, check the following:\n\";
        echo \"  <b>o</b> default.cfg.php - make sure the file is uploaded to the server\n\";
        echo \"                      more info in the file\n\";
        echo \"<br />\n\";
        echo \"</pre>\n</body>\n</html>\n\";
        exit;
    }
   
} //END if (!
$result)

while (
$result && @extract(@mysql_fetch_array($result, MYSQL_ASSOC))) {
    if (
$define=='true') {
        define(
$var, $val);
    }
    else {
       
${$var} = $val;
    }
} //END while
?>

Mark Hensler
If there is no answer on Google, then there is no question.

He has: 18 posts

Joined: Mar 2004

If I was going to use permissions for anything, and also use bitwase operators to uphold these permissions then I would do this.

1) Run this permission of a user database, as this would be a user by user type of thing, correct? In the user database I would make a section in the use column.

- Say you want to have a user setting to tell whether a user can use the site at all or not after logging in. In the db, in the users table you would add a row that says something along the lines of user_use_site , then you would make it a int(1) and it would either be set to 0 or 1 suggested default would be 1 for this.

- Then in the script you would do you little database connection thing, and make a variable in a global script to call global, or if it's a one script program you could just include it at the top.

<?php
$can_connect
= $db->connect(SELECT user_use_site  FROM  user_table);

if (!
$can_connect) {
  die(
'You do not have any permission to do this.');
}
?>

Chroder's picture

He has: 91 posts

Joined: Mar 2004

The point behind using bitwise operators would to condense a bunch of these TINYINT(1) columns into one INT. For example, I can have an INT() permission. Here are some example permissions:

View site: 1
Post: 2
Delete: 4
Moderate: 8
'
Then the column would hold, say 7. Then I'd use the bitwise operators to see if the action they're doing is acceptable.

<?php
// they're trying to moderate
define('VIEW', 1);
define('POST', 2);
define('DELETE', 4);
define('MOD', 8);

if(
$user['permission'] & MOD)
{
   
/// they're allowed
}
?>

Chroder's picture

He has: 91 posts

Joined: Mar 2004

If that were in binary, I think something like this.

(7 = 0111, 8 = 1000)
0111 &
1000
______
0000

Which is false.
'

Now if they wanted to DELETE, they have a permission of 7 so they can.

(7 = 0111, 4 = 0100)
0111 &
0100
______
0100
'

Thats how it works, I think. lol

He has: 18 posts

Joined: Mar 2004

Chroder, I know that your idea fits better to this case. I just have a side question though. If you were going to use permission with the TINYINT or INT for that matter which would you 'personally' use if you didn't care whether the permissions were file-based or database?

Chroder's picture

He has: 91 posts

Joined: Mar 2004

I don't think it really matters if they're stoed in a flatfile or database. If I can figure out of to use these things, then I'm always ginna use this method Laughing out loud The downside is (however small) is that if someone goes into the database and see's "7" under permissions, they probably won't know that it means "View, Post, Delete."

I think I understood your question. I have some music on and its kinda got my mind wandering, I can hardly talk lol.

He has: 18 posts

Joined: Mar 2004

Why not just use binary permissions? 1's and 0's make it user per user thing.

Setup of the db something like this | = new row

username | can_view_site | can_do_something | can_do_something_else |

Everything after the username would be a 1 or 0. You could simply use an if statement like I made above to check these for the perms.

Chroder's picture

He has: 91 posts

Joined: Mar 2004

You could do that, but your creating extra columns to work with. Say you had 15 different permissions, creating a new column for each permission will create 15 more bytes per user (as well as looking ugly in phpMyAdmin Wink). Now you combine the permissions into one 4 byte INT() column, you've saved yourself 11 bytes per user.

I've been doing it the way you're saying for a while now, I've just decided to test out this "new way" and see how it works Laughing out loud It's neat Cool

He has: 18 posts

Joined: Mar 2004

That does make sense, though. I may or may not check it out. I've been orthodically making my own coding religion (Possible?) and holding tight to it. I'll look at what you said up there some more and consider looking it to it. I'm not really sure, but do you know how much that will come into play with PHP5 and the better OO format?

Chroder's picture

He has: 91 posts

Joined: Mar 2004

There's not going to be anything new added to the way PHP handles the bitwise operators, so I doubt PHP5 and OOP will have a great effect on this type of permission scheme. I first got the idea from vB3, it seems to be working great there Laughing out loud

He has: 18 posts

Joined: Mar 2004

If PHP5 really doesn't rely on it then I probably won't work it that much. I am really concentrating on trying to work around OO coding. (*Although xBB is probably the farthest thing from, but that's how they wanted it.*)

I've been working on a PHP5 strict discussion board system. A guy by the name of 0zone is developing his version of smartBB (new PHP5) and it's pretty clean and uses OOP a lot. I've been learning a lot off of that.

<?php
       
public function __construct () {
           
# Work out the load time:
           
$this->time_start = gettimeofday();
           
$this->time = time();
           
           
# Set error handeling:
           
ini_set('error_reporting', E_ALL);
           
#set_error_handler(array($this, 'error_report'));
?>

^^ Just a pretty looking example.

Chroder's picture

He has: 91 posts

Joined: Mar 2004

I don't get it... PHP5 doesn't "rely" on anything =/ You can turn just about anything into an object, permission systems or not.

He has: 18 posts

Joined: Mar 2004

No, you don't get it lol. PHP5 is developing into more of an OO type of language (IMO). I'm saying if PHP5 really isn't focusing on 'updating' those focuses then I'm not really going to take time to go into the deeply. Such as XML support, it's been completely redone. Therefore I'm taking the proper time to learn the changes to become fully adapted to it. Oh, and who can forget SQLite?

Chroder's picture

He has: 91 posts

Joined: Mar 2004

I just found it weird that you're comparing a programming technique to PHP's OOP development, 'tis all Sticking out tongue

Now that mySQL's license has be changed, I don't really care about SQLite. Wink

Either way, once PHP5 is out of the RC's I'll be buying a nice O'Reilly book on it Wink

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

PHP is not (and I don't believe ever will be) an Object Oriented Programming Language (OOPL). Just because a language allows you to define classes and create objects doesn't mean the langauge is an OOPL.

Java is a good example of an OOPL. Heck, just to perform math opperations, you need to utilize the Math object methods:
Math.pow(base, power)

The example I gave earlier was terrible. I'm going through a change in careers and I'm waking up 5 hours earlier than I'm used to. I feel like I have jet lag.

Here's another snippet from another project. The purpose of this code is to allow the script to function with a failed DB connection. The $cfg array has options which are set in a config file. After a successfull DB connection, the DB is queried for the latest settings and these lines update the $cfg array.

<?php
$cfg
['debug']['email']    = (($qry['debugmode'] & pow(2, _DBG_EMAIL)) > 0) ? true : false;
$cfg['debug']['quiet']    = (($qry['debugmode'] & pow(2, _DBG_QUIET)) > 0) ? true : false;
$cfg['debug']['loud']     = (($qry['debugmode'] & pow(2, _DBG_LOUD)) > 0) ? true : false;
$cfg['debug']['logdb']    = (($qry['debugmode'] & pow(2, _DBG_LOGDB)) > 0) ? true : false;
$cfg['debug']['logfile']  = (($qry['debugmode'] & pow(2, _DBG_LOGFILE)) > 0) ? true : false;
$cfg['debug']['query']    = (($qry['debugmode'] & pow(2, _DBG_QUERY)) > 0) ? true : false;
?>

Mark Hensler
If there is no answer on Google, then there is no question.

Chroder's picture

He has: 91 posts

Joined: Mar 2004

Thanks, but I don't understand why your showing me these examples...

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

Chroder wrote: If anyone could give me a link or just explain it a little, that would be great Smiling

I don't have many resources, so I often give examples.

I think you've already figured out what you were looking for. I gave the second example to show another application of bitfields.

The _DBG_ constants are bit offsets, rather than bit values. This was necessary as I needed to iterate through the debug array somewhere else in the project. I assigned the bitwise opperations into a boolean array because these values were used frequently. And it was better to waste memory on another boolean variable than to re-perform the bitwise operation everytime the permission/setting needed to be checked. (plus, it's hard to explain to users how to setup the config file with bitfields)

Just something else to consider when using bitfields.

Mark Hensler
If there is no answer on Google, then there is no question.

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.