【发布时间】:2012-11-07 08:00:21
【问题描述】:
// 嗨,我想用按位运算排除一个标志,但我不知道如何: // 这里是标志(它们来自文件系统迭代器)
define('CURRENT_AS_FILEINFO', 0);
define('CURRENT_AS_SELF', 16);
define('CURRENT_AS_PATHNAME', 32);
define('CURRENT_MODE_MASK', 240);
define('KEY_AS_PATHNAME', 0);
define('KEY_AS_FILENAME', 256);
define('FOLLOW_SYMLINKS', 512);
define('KEY_MODE_MASK', 3840);
define('NEW_CURRENT_AND_KEY', 256);
define('SKIP_DOTS', 4096);
define('UNIX_PATHS', 8192);
用户可以设置任何标志组合。 我需要检测是否设置了 CURRENT_AS_SELF 或 CURRENT_AS_PATHNAME, 所以这是我到目前为止的功能:
function containsPathnameOrSelfFlag($flags) {
if ($flags & (CURRENT_AS_PATHNAME | CURRENT_AS_SELF)) {
return true;
}
return false;
}
这是一个测试套件:
var_dump(containsPathnameOrSelfFlag(CURRENT_MODE_MASK | CURRENT_AS_PATHNAME)); // true, ok
var_dump(containsPathnameOrSelfFlag(CURRENT_AS_FILEINFO)); // false, ok
var_dump(containsPathnameOrSelfFlag(CURRENT_MODE_MASK | CURRENT_AS_FILEINFO)); // true, but false was expected, because neither CURRENT_AS_SELF nor CURRENT_AS_SELF were set, so my function is wrong
是否可以使用位运算符使函数通过第三种情况 (它应该返回 false ) ?
我在这里看到的问题是 CURRENT_MODE_MASK 的位与 CURRENT_AS_SELF 重叠 和 CURRENT_AS_PATHNAME 的位:
0000000000010000 : CURRENT_AS_SELF
0000000000100000 : CURRENT_AS_PATHNAME
0000000011110000 : CURRENT_MODE_MASK
0000000100000000 : KEY_AS_FILENAME
0000001000000000 : FOLLOW_SYMLINKS
0000111100000000 : KEY_MODE_MASK
0000000100000000 : NEW_CURRENT_AND_KEY
0001000000000000 : SKIP_DOTS
0010000000000000 : UNIX_PATHS
所以每次用户将 CURRENT_MODE_MASK 添加到标志时,我的函数 会认为 CURRENT_AS_SELF 和 CURRENT_AS_PATHNAME 也已设置,但事实并非如此。 我不知道如何解决这个问题。
【问题讨论】:
-
CURRENT_MODE_MASK 确实设置了 CURRENT_AS_SELF 和 CURRENT_AS_PATHNAME 标志...将其更改为
0000000011000000 -
感谢您的回答,但标志来自 FilesystemIterator 类,我无法更改它们,但也许我误解了 CURRENT_MODE_MASK 的工作原理
-
您必须以不同的方式检查标志。见我的answer。
-
我认为还值得注意的是
KEY_MODE_MASK在技术上没有设置为正确的值,因为KEY_MODE_MASK & FOLLOW_SYMLINKS返回一个真实的结果,即使FOLLOW_SYMLINKS与任何键都不相关标志。因此拥有$any_key_flag_set = $fsiObj->getFlags() & $fsiObj::KEY_MODE_MASK;将返回误报。KEY_MODE_MASK应该是 3328(从它的掩码中删除 512),或者FOLLOW_SYMLINKS应该是 16384 以将其从 3840 掩码中取出。
标签: php bit-manipulation