php 如何在php中实现位掩码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11880360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement a bitmask in php?
提问by AlexMorley-Finch
I'm not sure if bitmask is the correct term. Let me explain:
我不确定位掩码是否是正确的术语。让我解释:
In php, the error_reportingfunction can be called multiple ways:
在 php 中,error_reporting可以通过多种方式调用该函数:
// 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);
I got the term bitmask from the php.net page here
我从这里的 php.net 页面得到了术语位掩码
Anyway the point of this is, I have implemented a SIMPLE method called lswhich returns the contents of a directory.
无论如何,重点是,我已经实现了一个简单的方法,调用ls它返回目录的内容。
This function takes 3 args... ( $include_hidden = false, $return_absolute = false, $ext = false )
这个函数需要 3 个参数...( $include_hidden = false, $return_absolute = false, $ext = false )
So when i call the function, i set how i want the results. Whether i want the results to return hidden directories, whether i want basenames only etc.
所以当我调用函数时,我设置了我想要的结果。我是否希望结果返回隐藏目录,是否只需要基本名称等。
so when i call the function i'm writing
所以当我调用我正在写的函数时
ls(true, false, true)
ls(false, false, true)
ls(true, true, true)
etc...
I thought it would be much more readable if i could just flag how i want the data returned?
我认为如果我可以标记我希望如何返回数据,它会更具可读性?
so something like:
所以像:
ls( INCLUDE_HIDDEN | HIDE_EXTS );
ls( SHOW_ABSOLUTE_PATHS | HIDE_EXTS );
etc...
等等...
How would i implement this in terms of testing which flags have been called?
在测试调用了哪些标志方面,我将如何实现这一点?
回答by DaveRandom
It's quite simple actually. First a bit of code to demonstrate how it can be implemented. If you don't understand anything about what this code is doing or how it works, feel free to ask additional questions in the comments:
其实很简单。首先是一些代码来演示它是如何实现的。如果您对这段代码在做什么或它如何工作不了解,请随时在评论中提出其他问题:
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);
Because the flags are integers, on a 32-bit platform you define up to 32 flags. On a 64-bit platform, it's 64. It is also possible to define the flags as strings, in which case the number of available flags is more or less infinite (within the bounds of system resources, of course). Here's how it works in binary (cut down to 8-bit integers for simplicity).
因为标志是整数,所以在 32 位平台上最多可以定义 32 个标志。在 64 位平台上,它是 64。也可以将标志定义为字符串,在这种情况下,可用标志的数量或多或少是无限的(当然,在系统资源的范围内)。这是它在二进制中的工作方式(为简单起见,减少到 8 位整数)。
FLAG_1
Dec: 1
Binary: 00000001
FLAG_2
Dec: 2
Binary: 00000010
FLAG_3
Dec: 4
Binary: 00000100
// And so on...
When you combine the flags to pass them to the function, you OR them together. Let's take a look at what happens when we pass FLAG_1 | FLAG_3
当您组合标志以将它们传递给函数时,您将它们组合在一起。让我们来看看当我们通过时会发生什么FLAG_1 | FLAG_3
00000001
| 00000100
= 00000101
And when you want to see which flags were set, you AND the bitmask with the flag. So, lets take the result above and see if FLAG_3was set:
当您想查看设置了哪些标志时,您可以将位掩码与标志进行 AND 运算。因此,让我们采用上面的结果,看看是否FLAG_3已设置:
00000101
& 00000100
= 00000100
...we get the value of the flag back, a non-zero integer - but if we see if FLAG_2was set:
...我们取回标志的值,一个非零整数 - 但如果我们查看是否FLAG_2已设置:
00000101
& 00000010
= 00000000
...we get zero. This means that you can simply evaluate the result of the AND operation as a boolean when checking if the value was passed.
...我们得到零。这意味着在检查值是否通过时,您可以简单地将 AND 运算的结果评估为布尔值。
回答by Esailija
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..
You can then check for individual flags in your lsfunction:
然后,您可以检查ls函数中的各个标志:
if( $flags & INCLUDE_HIDDEN ) { //<-- note just a single &, bitwise and
//$flags have INCLUDE_HIDDEN
}
回答by Simon East
The others have offered good suggestions, but these days it's much more common to pass in associative arraysinstead of bitmasks. It's much more readable and allows you to pass in other variables other than just true/false values. Something like this:
其他人提供了很好的建议,但现在更常见的是传入关联数组而不是位掩码。它更具可读性,并允许您传入除真/假值以外的其他变量。像这样的东西:
myFunction(['includeHidden' => true, 'fileExts' => false, 'string' => 'Xyz']);
function myFunction($options) {
// Set the default options
$options += [
'includeHidden' => false,
'fileExts' => true,
'string' => 'Abc',
];
if ($options['includeHidden']) {
...
}
...
}

