2012-08-09 82 views
60

我不確定位掩碼是否正確。讓我來解釋:如何在php中實現位掩碼?

在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頁here

反正這點是長期位掩碼,我實現了一個叫做ls的SIMPLE方法,它返回一個目錄的內容。

這個函數有3名ARGS ...($ include_hidden =假,$ return_absolute =假,$ 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); 

等等

我怎麼會在這標誌已經被稱爲測試方面實現這一點?

+1

好問。 KISS – Nico 2015-10-26 17:14:26

回答

121

這是很簡單的實際。首先介紹一些代碼來演示如何實現它。如果你不理解的任何事情這個代碼做什麼或它是如何工作的,隨便問其他問題的意見:

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); 

Demo


因爲國旗是整數,上一個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 

...我們得到的標誌的值後面,一個非零整數 - 但如果我們看看設置:

00000101 
& 00000010 
= 00000000 

...我們得到零。這意味着您可以在檢查值是否通過時簡單地將AND操作的結果評估爲布爾值。

+5

所以基本的按位操作是:'$ flags&FLAG_1' - 檢查是否設置了FLAG_1 ,'$ flags | FLAG_1' - 設置FLAG_1,'$ flags&〜FLAG_1' - 取消設置FLAG_1,'〜$ flags' - 反轉標誌 – 2013-11-01 16:53:33

+5

我不知道PHP並且可能永遠不會學習它,但很高興我偶然發現了這個問題 - 你的解釋可以幫助任何人實現任何語言的位映射:) – 2013-12-03 04:29:43

+3

我會建議定義功率2小數爲1的位移操作。'define('FLAG_1',1 << 0); define('FLAG_2',1 << 2); define('FLAG_3',1 << 3); define('FLAG_4',1 << 4);'這是通常在C – AmitP 2014-01-06 16:12:32

14
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 
} 
+7

你知道使用十六進制數字而不是整數的好處嗎?只是好奇:) – 2014-09-16 14:21:19

+0

@ AlexMorley-Finch看起來像純粹的偏好,使用小數或十六進制似乎根本沒有改變執行時間,要麼 – 2018-01-22 19:38:13

3

其他人提供了很好的建議,但現在通過關聯數組而不是位掩碼更爲常見。它更可讀,並允許您傳遞其他變量,而不僅僅是true/false值。這樣的事情:

myFunction(['includeHidden' => true, 'fileExts' => false, 'string' => 'Xyz']); 

function myFunction($options) { 
    // Set the default options 
    $options += [ 
     'includeHidden' => false, 
     'fileExts' => true, 
     'string' => 'Abc', 
    ]; 

    if ($options['includeHidden']) { 
     ... 
    } 
    ... 
} 
+0

我也是這樣做的,但同伴們抱怨他們的IDE沒有「類型暗示」,沒有合適的[doc comments](https://en.wikipedia.org/wiki/PHPDoc)和函數不會[在需要的參數不通過時拋出錯誤](http://symfony.com/doc/current/components/options_resolver.html)。理想情況下,「命名參數」將解決所有這些問題,如果它們存在於php – 2015-10-31 08:43:47

+0

Hi @TimoHuovinen - 感謝評論。添加概述選項和默認值的doc註釋非常簡單,如果需要可以引發異常,並將參數默認爲允許提示類型的數組。這對你有用嗎? – 2015-10-31 08:49:30

+0

哦,我明白了。 Symfony OptionsResolver類進一步提供更多功能。涼。 – 2015-10-31 08:53:58