我不确定bitmask是否是正确的术语。让我解释一下:
在 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);
我从这里的 php.net 页面获得了术语位掩码
无论如何,这样做的重点是,我已经实现了一个名为 ls
的 SIMPLE 方法,该方法返回目录的内容。
此函数需要 3 个参数...( $include_hidden = false, $return_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 );
等。。。
在测试调用了哪些标志方面,我将如何实现这一点?
其实很简单。首先是一些代码来演示如何实现它。如果您对这段代码的作用或工作原理一无所知,请随时在评论中提出其他问题:
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);
演示
由于标志是整数,因此在 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...
当您组合标志以将它们传递给函数时,您或将它们放在一起。让我们来看看当我们通过FLAG_1 | FLAG_3
时会发生什么
00000001
| 00000100
= 00000101
当您想查看设置了哪些标志时,您和带有标志的位掩码。因此,让我们采用上面的结果,看看是否设置了FLAG_3
:
00000101
& 00000100
= 00000100
。我们得到标志的值,一个非零整数 - 但如果我们看到是否设置了FLAG_2
:
00000101
& 00000010
= 00000000
。我们得到零。这意味着在检查值是否已传递时,您可以简单地将 AND 运算的结果作为布尔值进行评估。
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
}
其他人提供了很好的建议,但如今传递关联数组而不是位掩码更为常见。 它的可读性要高得多,并允许您传入除真/假值以外的其他变量。 像这样:
myFunction(['includeHidden' => true, 'fileExts' => false, 'string' => 'Xyz']);
function myFunction($options) {
// Set the default options
$options += [
'includeHidden' => false,
'fileExts' => true,
'string' => 'Abc',
];
if ($options['includeHidden']) {
...
}
...
}
我有一个正在使用的 API - 文档非常薄。它给了我们一个整数,并说:
"信息在这些值中编码为位字段。位字段的工作原理是在同一整数中存储多个真/假值,而不是为每个值存储多个整数。要在位字段中查找值,您需要使用位掩码。
Bit Decimal Value Setting
0 1 Display
1 2 Sell
2 4 Kiosk Display
3 8 No Passes
4 16 Dolby Digital
5 32 THX
6 64 DLP
[etc]
我根据这里的其他答案想出了如何解决它,尽管我会分享我想出的功能。
我最终编写了这个函数:
<?php
function bitmap_decode( $label_array, $value, $return_item ) {
$label_array = array_flip( $label_array ); // swap the keys and values
$i = $label_array[ $return_item ]; // get the decimal key value for the item on the list
$i = 2**$i; // use 2 to the nth power to get the decimal bitmap value for the item
return $value & $i ? 1 : 0; // use the & operator to determine if the value is true or false. return 1 or 0 accordingly
}
。这将解析出值
$info1 = array(
'Display',
'Sell',
'Kiosk Display',
'No Passes',
'Dolby Digital',
'THX',
'DLP',
);
$api_value = 5;
echo bitmap_decode( $info1, $api_value, 'Sell' ); // 0
$api_value = 35;
echo bitmap_decode( $info1, $api_value, 'Sell' ); // 1
然后我们可以做相反的事情 - 对值进行编码,而不必考虑任何非二进制数或类似的东西:
function bitmap_encode( $items, $label_array ) {
$return = 0;
$label_array = array_flip( $label_array ); // swap the keys and values
foreach ( $items as $item ) {
$i = $label_array[ $item ]; // get the decimal key value for the item on the list
$i = 2**$i; // use 2 to the nth power to get the decimal bitmap value for the item
$return += $i; // add $i to the return value
}
return $return;
}
// set these flags as true
$flags = array( 'Display', 'Sell', 'THX' );
echo bitmap_encode( $flags, $info1 ); // 35
我知道这并不能准确回答 OP 问题,但这是在 PHP 中制作位掩码系统的另一种方法。