3

有時編程,他們允許一個鏈參數如下面的第二個輸入變量的單一功能的輸入變量:如何測試PHP位運算功能輸入參數

define('FLAGA',40); 
define('FLAGB',10); 
define('FLAGC',3); 
function foo($sFile, $vFlags) { 
    // do something 
} 
foo('test.txt',FLAGA | FLAGB | FLAGC); 

PHP調用此單管字符(|)按位OR運營商。我現在如何在foo()內添加一些東西來測試$vFlags以查看哪些標誌已設置?

回答

4

我想你會發現,這樣的標誌通常定義爲2的冪,如:

define('FLAGA',1); 
define('FLAGB',2); 
define('FLAGC',4); /* then 8, 16, 32, etc... */ 

正如你正確指出的那樣,這些都可以通過使用位或操作符組合:

foo('test.txt',FLAGA | FLAGB | FLAGC); 

要測試你的函數裏面這些標誌,你需要按如下方式使用位AND運算符:

function foo($sFile, $vFlags) { 
    if ($vFlags & FLAGA) { 
    // FLAGA was set 
    } 
    if ($vFlags & FLAGB) { 
    // FLAGB was set 
    } 
    //// etc... 
} 
2

「flags」參數將被稱爲位掩碼。一個字節包含8位,可以設置或不設置。你只需將自己的意思分配給每一位;如果它被設置,則意味着,否則沒有

因此,您需要首先定義標誌,並設置正確的值來設置正確的位;只是任意數字不會出現在正確的方式結合在一起:

define('FLAGA', 1); // 00000001 
define('FLAGB', 2); // 00000010 
define('FLAGC', 4); // 00000100 
define('FLAGD', 8); // 00001000 

鑑於上述情況,FLAGB | FLAGD創建與第二和第四位設置(00001010)的位掩碼。爲此,您需要在基數2(二進制)和基數10(十進制)之間進行轉換。

爲了測試這一點,您使用&

$flags = FLAGB | FLAGD; 

if ($flags & FLAGA) { 
    echo 'flag A is set'; 
} 

if ($flags & FLAGB) { 
    echo 'flag B is set'; 
} 

.. 
0

你需要按位AND運營商&

define('FLAGA',40); 
define('FLAGB',10); 
define('FLAGC',3); 

function foo($sFile, $vFlags) { 
    if ($vFlags & FLAGA) { 
    echo "FLAGA is set\n"; 
    } 
    if ($vFlags & FLAGB) { 
    echo "FLAGB is set\n"; 
    } 
    if ($vFlags & FLAGC) { 
    echo "FLAGC is set\n"; 
    } 
} 
foo('test.txt',FLAGA | FLAGB | FLAGC); 

DEMO

這就是說,按位操作必然在以下方面工作二進制,其中每個位代表2的冪。因此,您通常會想要d以2的冪efine標誌,如

define('FLAGA',1); 
define('FLAGB',2); 
define('FLAGC',4); 
define('FLAGD',8); // etc. 

否則,可以想象這樣的場景:

define('FLAGA',8); 
define('FLAGB',32); 
define('FLAGC',40); 

如果你有一個價值40 $vFlags,你不能告訴設置了什麼樣的標誌;它可能是以下任何一種:

FLAGA & FLAGB 
FLAGA & FLAGB & FLAGC 
FLAGA & FLAGC 
FLAGB & FLAGC 
FLAGC