gpt4 book ai didi

php - 如何使用功能标志?

转载 作者:可可西里 更新时间:2023-10-31 22:42:11 24 4
gpt4 key购买 nike

我想创建一个类并扩展一个 PHP 类 FilesystemIterator,如下面的代码所示。我定义了一个方法 hasFlag() 并测试它是否包含一个标志(我希望它像其他一些 PHP 函数一样,例如 glob),但结果总是与预期不同。那么我该如何解决这个问题呢?

class c extends FilesystemIterator 
{
/* These are parent constants */
const CURRENT_AS_FILEINFO = 0 ;
const KEY_AS_PATHNAME = 0 ;
const CURRENT_AS_SELF = 16 ;
const CURRENT_AS_PATHNAME = 32 ;
const CURRENT_MODE_MASK = 240 ;
const KEY_AS_FILENAME = 256 ;
const NEW_CURRENT_AND_KEY = 256 ;
const FOLLOW_SYMLINKS = 512 ;
const KEY_MODE_MASK = 3840 ;
const SKIP_DOTS = 4096 ;
const UNIX_PATHS = 8192 ;

public function __construct($flags) {
$this->flags = $flags;
}
public function hasFlag($flag) {
//How do I test $this->flags it contains a $flag???
return ($this->flags & $flag) ? true : false;
}
}

$c = new c(
c::CURRENT_AS_FILEINFO |
c::KEY_AS_PATHNAME |
c::CURRENT_AS_SELF |
c::CURRENT_AS_PATHNAME |
c::CURRENT_MODE_MASK |
c::KEY_AS_FILENAME |
c::NEW_CURRENT_AND_KEY |
c::FOLLOW_SYMLINKS |
c::KEY_MODE_MASK |
c::SKIP_DOTS |
c::UNIX_PATHS
);

var_dump($c->hasFlag(c::CURRENT_AS_FILEINFO));

编辑 1

为什么会这样??

var_dump( ((0 | 16 | 32 | 240 | 3840) & 0)    == 0 );    //true
var_dump( ((0 | 16 | 32 | 240 | 3840) & 32) == 32 ); //true
var_dump( ((0 | 16 | 32 | 240 | 3840) & 240) == 240 ); //true
var_dump( ((0 | 16 | 32 | 240 | 3840) & 1024) == 1024 ); //true??
var_dump( ((0 | 16 | 32 | 240 | 3840) & 2048) == 2048 ); //true??
var_dump( ((0 | 16 | 32 | 240 | 3840) & 3840) == 3840 ); //true

最佳答案

关于默认值和掩码

FilesystemIterator 中使用了一些特殊标志,被称为口罩;它们将多个相关的标志组合在一起(或者在这种情况下,相互排斥)并且不应作为常规标志传递;;下面是它们的二进制表示:

000x00xx0000
+--++--+
| |
| +---- CURRENT_MODE_MASK
|
+-------- KEY_MODE_MASK

这些标志用于确定是否应使用默认的 key()current() 方法。这两种方法的默认值都在此处定义:

const CURRENT_AS_FILEINFO  = 0 ;
const KEY_AS_PATHNAME = 0 ;

以下代码说明了如何对其进行测试:

if ($flags & CURRENT_MODE_MASK == 0) {
// CURRENT_AS_FILEINFO is used
} else {
// either CURRENT_AS_PATHNAME, CURRENT_AS_SELF or CURRENT_AS_PATHNAME is used
}

if ($flags & KEY_MODE_MASK == 0) {
// KEY_AS_PATHNAME is used
} else {
// KEY_AS_FILENAME is used
}

->hasFlag() 等函数的问题在于您无法区分这两个默认值,即您是想测试 CURRENT_AS_FILEINFO 还是KEY_AS_PATHNAME?您将不得不重新考虑逻辑。

关于互斥标志

有一些标志不能一起使用,因为它们会导致未定义的行为;例如:

const CURRENT_AS_SELF      = 16 ;
const CURRENT_AS_PATHNAME = 32 ;

您不能为 current() 定义两种类型的行为,应该使用其中一种(或默认)。一组兼容的标志可能是这样的:

$c = new c(
c::CURRENT_AS_SELF |
c::KEY_AS_FILENAME |
c::FOLLOW_SYMLINKS |
c::SKIP_DOTS |
c::UNIX_PATHS
);

关于扩展类

假设您的构造函数与父构造函数相同,您可以完全删除构造函数:

class c extends FilesystemIterator 
{
public function hasFlag($flag)
{
$flags = $this->getFlags(); // use parent function here
// logic here
}
}

关于php - 如何使用功能标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16375138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com