Php 这个按位AND运算符的用途是什么?

Php 这个按位AND运算符的用途是什么?,php,mysql,Php,Mysql,代码是cms的基本php代码,它读取Mysql内容以基于三种不同的方法呈现网页,按id、名称或特殊类型索引页、站点地图页……但我无法理解这一行$r=dbRowselect*,其中特殊($v limit 1);按位和应该做什么 <?php class Page{ static $instances = array(); static $instancesByName = array(); static $instancesBySpeci

代码是cms的基本php代码,它读取Mysql内容以基于三种不同的方法呈现网页,按id、名称或特殊类型索引页、站点地图页……但我无法理解这一行$r=dbRowselect*,其中特殊($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似乎包含一个,即其值中的每个位位置都将标记某些特定于应用程序的属性

然后,要查找具有某些属性的记录,将执行逐位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 | +---------+------+------------+ 由于MySQL没有true boolean类型,而是将零视为false,将非零视为true,因此筛选器表达式可以缩写为:

从包含特殊内容的页面中选择*&0b11 我们也可以用十进制而不是二进制形式表示掩码:

从特殊页面中选择*(&3) 并且,如果需要,对查询应用限制,尽管在没有ORDER BY子句的情况下,结果是不确定的:

从特殊和3限制为1的页面中选择* 考虑到这是您展示的代码中我们需要处理的全部内容,我们只能说:

查询从pages表中选择不确定记录的所有列,其中special的值至少有一个与掩码$v中设置的位相同

由于special和$v的语义以及其中的位位置都是特定于应用程序的,因此如果不深入了解您的应用程序,就不可能再说更多


请注意,虽然结构紧凑,但在位字段上使用掩码进行过滤是不可取的,因此这往往是非常糟糕的数据库设计。

这没什么,只是字段名称中的一种不好的做法。如果$v值是abc,那么字段名将是special&abc。如果我们不知道$v是什么,那么很难回答。我只是认为它是一个数字,或者某种ID,以及special包含的内容。不管怎么说,如果你遇到编写这段代码的人,请打他的耳光。看起来这种编码是MySQL允许的。在这种情况下,如果$special是一个数字,$v是一个数字,那么查询将根据按位and得到的特殊值来选择页面;看见