这段代码是cms的基本php代码,它根据三种不同的方法(id、名称或特殊类型(索引页、站点地图页……)读取Mysql内容来呈现网页,但我不明白这行“$r=dbRow(“select*from pages where special&$v limit 1”);”按位应该做什么?

<?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];
    }
}

最佳答案

似乎pages.special包含一个bit field(即,其值中的每个位位置都将标记某些特定于应用程序的属性)。
然后,要查找具有某些属性的记录,可以使用所需的“掩码”执行逐位AND操作-仅当在值和掩码中设置了相同的位置时,才会设置结果中的位位置。2位值的完整真值表如下所示:

+---------+------+------------+
|  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

由于MySQL没有真布尔类型(而是将零视为假,将非零视为真),因此筛选器表达式可以缩写为:
SELECT * FROM pages WHERE special & 0b11

我们还可以用十进制而不是二进制形式声明掩码:
SELECT * FROM pages WHERE special & 3

如果需要,对查询应用LIMIT(尽管在没有ORDER BY子句的情况下,结果是不确定的):
SELECT * FROM pages WHERE special&3 LIMIT 1

考虑到这是我们需要处理的所有问题(从您显示的代码中),我们只能说:
查询从pages表中选择一个不确定记录的所有列,其中special的值至少有一个与掩码$v中设置的位相同。
由于special$v的语义(以及其中的位位置)是特定于应用程序的,因此如果不深入了解应用程序,就不可能再多说什么。
注意,虽然很紧凑,但是在位字段上使用掩码进行过滤是不可搜索的,所以这往往是非常糟糕的数据库设计。

关于php - 这个按位与运算符的目的是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27501220/

10-12 12:33
查看更多