如何在php中实现位掩码?

如何在php中实现位掩码?,php,bitmask,Php,Bitmask,我不确定bitmask是否是正确的术语。让我解释一下: 在php中,可以通过多种方式调用错误报告函数: // Report simple running errors error_reporting(E_ERROR | E_WARNING | E_PARSE); // Reporting E_NOTICE can be good too (to report uninitialized // variables or catch variable name misspellings ...)

我不确定bitmask是否是正确的术语。让我解释一下:

在php中,可以通过多种方式调用
错误报告
函数:

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Reporting E_NOTICE can be good too (to report uninitialized
// variables or catch variable name misspellings ...)
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

// Report all errors except E_NOTICE
// This is the default value set in php.ini
error_reporting(E_ALL ^ E_NOTICE);
我从php.net页面获得了术语bitmask

无论如何,这一点是,我实现了一个名为
ls
的简单方法,它返回目录的内容

此函数需要3个参数。。。($include\u hidden=false,$return\u absolute=false,$ext=false)

因此,当我调用函数时,我设置了我想要结果的方式。我是否希望结果返回隐藏目录,是否只需要基本名称等

所以当我调用我正在编写的函数时

ls(true, false, true)
ls(false, false, true)
ls(true, true, true)
etc...
我想如果我可以标记我希望返回数据的方式,它会更具可读性

比如:

ls( INCLUDE_HIDDEN | HIDE_EXTS );
ls( SHOW_ABSOLUTE_PATHS | HIDE_EXTS );
等等

在测试调用了哪些标志方面,我将如何实现这一点

define( "INCLUDE_HIDDEN", 0x1 );
define( "HIDE_EXTS", 0x2 );
define( "SHOW_ABSOLUTE_PATHS", 0x4 );
//And so on, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800 etc..
然后,您可以在
ls
函数中检查各个标志:

if( $flags & INCLUDE_HIDDEN ) { //<-- note just a single &, bitwise and
    //$flags have INCLUDE_HIDDEN
}

if($flags&INCLUDE_HIDDEN){/实际上很简单。首先是一些代码来演示如何实现它。如果您不了解此代码的功能或工作原理,请在评论中提出其他问题:

const FLAG_1 = 0b0001; // 1
const FLAG_2 = 0b0010; // 2
const FLAG_3 = 0b0100; // 4
const FLAG_4 = 0b1000; // 8
// Can you see the pattern? ;-)

function show_flags ($flags) {
  if ($flags & FLAG_1) {
    echo "You passed flag 1!<br>\n";
  }
  if ($flags & FLAG_2) {
    echo "You passed flag 2!<br>\n";
  }
  if ($flags & FLAG_3) {
    echo "You passed flag 3!<br>\n";
  }
  if ($flags & FLAG_4) {
    echo "You passed flag 4!<br>\n";
  }
}

show_flags(FLAG_1 | FLAG_3);

当你将标志组合到函数中时,你或它们在一起。让我们来看看当我们通过<代码> Frave1Frave3

时会发生什么情况。
  00000001
| 00000100
= 00000101
当您想查看设置了哪些标志时,您可以使用该标志和位掩码。因此,让我们获取上面的结果,看看是否设置了
flag_3

  00000101
& 00000100
= 00000100
  00000101
& 00000010
= 00000000
…我们得到标志的值,一个非零整数-但是如果我们看到是否设置了
flag_2

  00000101
& 00000100
= 00000100
  00000101
& 00000010
= 00000000

…我们得到零。这意味着在检查值是否传递时,您可以简单地将AND运算的结果作为布尔值进行计算。

其他人提供了很好的建议,但现在传递关联数组而不是位掩码更为常见。它更具可读性,允许您传递ot她的变量不仅仅是真/假值。类似于:

myFunction(['includeHidden' => true, 'fileExts' => false, 'string' => 'Xyz']);

function myFunction($options) {
    // Set the default options
    $options += [
        'includeHidden' => false,
        'fileExts' => true,
        'string' => 'Abc',
    ];

    if ($options['includeHidden']) {
        ...
    }
    ...
}

所以基本的位操作是:
$flags&FLAG\u 1
-检查FLAG\u 1是否设置,
$flags&FLAG\u 1
-设置FLAG\u 1,
$flags&FLAG\u 1
-取消设置FLAG\u 1,
~$flags
-反转FLAG我不懂PHP,可能永远也学不懂,但我很高兴我偶然发现了这个问题-你的解释可以帮助任何人实现任何语言中的位映射:)我建议将幂2小数定义为1的逐位移位操作。
define('FLAG_1',1@AmitPPHP中的这种方法有几个(次要)问题。1)当前
const
关键字不支持表达式,即使结果是常量(也就是说,
const FLAG_1=1@Benjamin与这个问题无关,但是你可以用const标量表达式做一件有用的事情:
const IS_WINDOWS=\PHP\u OS&“\xDF\xDF\xDF\xDF”==='WIN';
是非常常见的
stripos(\PHP\u OS,'WIN')==0
习惯用法的编译时等价物。目前这是毫无意义的(
PHP_OS
目前在所有版本的Windows上都是
'WINNT'
),但我想这是未来的证明……你知道使用十六进制数而不是整数的优势吗?只是好奇:)@亚历克斯莫利·芬奇(AlexMorley Finch)看起来纯粹是偏好,使用小数或十六进制似乎根本不会改变执行时间,尽管我以前也是这样做的,但同伴们抱怨说,他们的IDE中没有“类型暗示”,没有正确的,函数也没有。理想情况下,“命名参数”如果在phpHi@TimoHuovinen中存在这些问题,它们将解决所有这些问题-感谢您的评论。添加文档注释很容易,概述了选项和默认值,如果需要,抛出异常,并将参数默认为允许类型提示的数组。这对您有用吗?哦,我明白了。Symfony OptionsResolver类是更进一步,提供更多功能。酷。“添加概述选项和默认值的文档注释很容易”是的,你可以像这样添加它们,但这仍然是一个解决办法。“并将参数默认为允许类型提示的数组”你会怎么做呢?我指的是IDE类型提示和代码完成,编辑器会告诉你函数可以接受哪些参数。(记住,我也喜欢使用数组作为选项,只是我需要弄清楚如何让同伴满意)这种方法的问题是,你最终会遇到大量的if-else语句