bitmask2.php

<?php
// http://mark-story.com/posts/view/using-bitmasks-to-indicate-status

/*
CREATE TABLE nodes (
	id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(100),
	description TEXT,
	STATUS INT(3),
	created DATETIME,
	modified DATETIME
);
*/

class Node extends AppModel
{
	const PUBLISHED = 1;
	const NEEDS_REVIEW = 2;
	const COMMENTS_ALLOWED = 4;
	const PROMOTED = 8;
}

// Add status
$publishedAndCommentsAllowed = Node::PUBLISHED | Node::COMMENTS_ALLOWED; // value = 5
$commentsAllowedPublishedPromoted = Node::PUBLISHED | Node::COMMENTS_ALLOWED | Node::PROMOTED; // value = 13

// Subtract status
$published = $publishedAndCommentsAllowed & ~Node::COMMENTS_ALLOWED; // value = 1
$published = $commentsAllowedPublishedPromoted & ~Node::COMMENTS_ALLOWED & ~Node::PROMOTED;

// Check status
$status = 5; // (0101) published and comments_allowed set.
if($status & Node::PUBLISHED) {
	echo 'published';
}

$status = 13; // (1101) published, promoted and comments_allowed set.
if($status & Node::PROMOTED) {
	echo 'promoted';
}


// Extended find() in CakePHP with MySQL
$conditions = array(
	'(Node.status & ? = ?)' => array(Node::PUBLISHED, Node::PUBLISHED),
);


?>