Reputation: 3228
The code is basic php code for a cms,It read Mysql content to render web page based on three different methods ,by id,name or special type(index page,sitemap page ...).But I can't understand this line " $r=dbRow("select * from pages where special&$v limit 1");" what is the bitwise AND supposed to do ?
<?php
class Page{
static $instances = array();
static $instancesByName = array();
static $instancesBySpecial = array();
function __construct($v,$byField=0,$fromRow=0,$pvq=0){
# byField: 0=ID; 1=Name; 3=special
if (!$byField && is_numeric($v)){ // by ID
$r=$fromRow?$fromRow:($v?dbRow("select * from pages where id=$v limit 1"):array());
}
else if ($byField == 1){ // by name
$name=strtolower(str_replace('-','_',$v));
$fname='page_by_name_'.md5($name);
$r=dbRow("select * from pages where name like '".addslashes($name)."' limit 1");
}
else if ($byField == 3 && is_numeric($v)){ // by special
$fname='page_by_special_'.$v;
$r=dbRow("select * from pages where special&$v limit 1");
}
else return false;
if(!count($r || !is_array($r)))return false;
if(!isset($r['id']))$r['id']=0;
if(!isset($r['type']))$r['type']=0;
if(!isset($r['special']))$r['special']=0;
if(!isset($r['name']))$r['name']='NO NAME SUPPLIED';
foreach ($r as $k=>$v) $this->{$k}=$v;
$this->urlname=$r['name'];
$this->dbVals=$r;
self::$instances[$this->id] =& $this;
self::$instancesByName[preg_replace('/[^a-z0-9]/','-',strtolower($this->urlname))] =& $this;
self::$instancesBySpecial[$this->special] =& $this;
if(!$this->vars)$this->vars='{}';
$this->vars=json_decode($this->vars);
}
function getInstance($id=0,$fromRow=false,$pvq=false){
if (!is_numeric($id)) return false;
if (!@array_key_exists($id,self::$instances)) self::$instances[$id]=new Page($id,0,$fromRow,$pvq);
return self::$instances[$id];
}
function getInstanceByName($name=''){
$name=strtolower($name);
$nameIndex=preg_replace('#[^a-z0-9/]#','-',$name);
if(@array_key_exists($nameIndex,self::$instancesByName))return self::$instancesByName[$nameIndex];
self::$instancesByName[$nameIndex]=new Page($name,1);
return self::$instancesByName[$nameIndex];
}
function getInstanceBySpecial($sp=0){
if (!is_numeric($sp)) return false;
if (!@array_key_exists($sp,$instancesBySpecial)) $instancesBySpecial[$sp]=new Page($sp,3);
return $instancesBySpecial[$sp];
}
}
Upvotes: 1
Views: 381
Reputation: 125865
It appears that pages.special
contains a bit field (that is, each bit position in its values would flag some application-specific property).
Then, to find records that have certain properties, one would perform a bitwise AND
operation with the desired "mask"—bit positions in the result are set only if the same position was set in both the value and the mask. A complete truth-table for a 2-bit value would look like this:
+---------+------+------------+ | value | mask | value&mask | +---------+------+------------+ | 0b00 | 0b00 | 0b00 | | 0b01 | 0b00 | 0b00 | | 0b10 | 0b00 | 0b00 | | 0b11 | 0b00 | 0b00 | | 0b00 | 0b01 | 0b00 | | 0b01 | 0b01 | 0b01 | | 0b10 | 0b01 | 0b00 | | 0b11 | 0b01 | 0b01 | | 0b00 | 0b10 | 0b00 | | 0b01 | 0b10 | 0b00 | | 0b10 | 0b10 | 0b10 | | 0b11 | 0b10 | 0b10 | | 0b00 | 0b11 | 0b00 | | 0b01 | 0b11 | 0b01 | | 0b10 | 0b11 | 0b10 | | 0b11 | 0b11 | 0b11 | +---------+------+------------+
For example, suppose the lowest-order bit is a flag that the respective page "is readonly"; and the next bit that the page "requires moderation"—a value of (decimal) 2, or 0b10
, would indicate that the page is not readonly but does require moderation. So, to find all pages that either are readonly or require moderation, one could do:
SELECT * FROM pages WHERE (special & 0b11) != 0
Because MySQL doesn't have true boolean types (but instead treats zero as false and non-zero as true), the filter expression can be abbreviated:
SELECT * FROM pages WHERE special & 0b11
We could also state the mask in decimal, rather than binary, form:
SELECT * FROM pages WHERE special & 3
And, if so desired, apply a LIMIT
to the query (although in the absence of an ORDER BY
clause, the result is indeterminate):
SELECT * FROM pages WHERE special&3 LIMIT 1
Given that is all we have to work with (from the code that you have shown), we can only say the following:
The query selects all columns of an indeterminate record from the pages
table for which the value of special
has at least one of the same bits set as in the mask $v
.
Since the semantics of special
and $v
(and the bit positions within them) are application-specific, it is impossible for one to say anything more without a deeper understanding of your application.
Note that, whilst compact, filtering using a mask on a bit field is not sargable—so this tends to be very poor database design.
Upvotes: 3