2012-08-09 17 views
60

Bitmask'ın doğru terim olup olmadığından emin değilim. Anlatayım:Php'de bir bit maskesi nasıl uygulanır?

php olarak error_reporting işlev çağrılabilir birden çok yolu:

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

Ben, php.net sayfa here

Neyse bunun noktasıdır gelen terim bit maskesi var Bir dizinin içeriğini döndüren ls adlı bir SIMPLE yöntemini uyguladım.

Bu fonksiyon 3 args ... ($ include_hidden = false, $ return_absolute = false, $ ext = false) i işlevini çağırdığınızda

Yani, ben sonucu nasıl ayarlanır alır. i isteyin sonuçları i düşündüm ben

ls(true, false, true) 
ls(false, false, true) 
ls(true, true, true) 
etc... 

yazıyorum işlevini çağırdığınızda ı tekini eğer öyleyse çok daha okunabilir olacaktır sadece vs.

basenames isteyip, gizli dizinleri dönmek için veriyi nasıl geri almak istiyorum?

şöyle bir şey:

ls(INCLUDE_HIDDEN | HIDE_EXTS); 
ls(SHOW_ABSOLUTE_PATHS | HIDE_EXTS); 

vs ...

Nasıl denilen edilmiş bayrakları test açısından bu uygulamaya koyacak?

+1

sordu. KISS – Nico

cevap

121

Aslında oldukça basit. İlk nasıl uygulanabileceğini göstermek için bir kod. Eğer hakkında hiçbir şey anlamadıysanız bu kod yapıyor ya nasıl çalıştığını, yorumlardaki ek soru sormak için çekinmeyin ne:

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


bayrakları tamsayılar olduğundan, üzerinde 32 bitlik bir platformda 32 adete kadar bayrak tanımlarsınız. 64-bit bir platformda, 64'dür. Bayrakları dizgiler olarak tanımlamak da mümkündür, bu durumda mevcut bayrakların sayısı az ya da çok sınırlıdır (tabii ki sistem kaynaklarının sınırları dahilinde). İşte ikili olarak nasıl çalışır (basitlik için 8-bit tam sayılara kadar kesilir).

FLAG_1 
Dec: 1 
Binary: 00000001 

FLAG_2 
Dec: 2 
Binary: 00000010 

FLAG_3 
Dec: 4 
Binary: 00000100 

// And so on... 

Bayrakları, işleve iletmek için birleştirdiğinizde, siz birlikte veya birlikte. Biz FLAG_1 | FLAG_3

00000001 
| 00000100 
= 00000101 

geçtiğinde Ve bayraklar, sizi VE bayrağıyla bit maskesi kuruldu hangi görmek istediğinizde neler olduğuna birlikte bakalım. Yani, yukarıda sonuç almak ve FLAG_3 kuruldu görelim:

00000101 
& 00000100 
= 00000100 

...

00000101 
& 00000010 
= 00000000 

... biz sıfır olsun: kurulmuştur görüyoruz ama eğer - biz geri bayrağının değerini, sıfırdan farklı tamsayı olsun. Bu, değerin geçip geçmediğini kontrol ederken AND işleminin sonucunu bir boole olarak değerlendirebileceğiniz anlamına gelir.

+5

Yani temel bit işlemleri şunlardır: '$ flags & FLAG_1' - FLAG_1 ayarlanmış olup olmadığını kontrol edin , '$ bayraklar | FLAG_1' - FLAG_1, '$ flags & ~ FLAG_1' ayarlandı - FLAG_1,' ~ $ flags' öğesinin - invert bayrakları sıfırlandı –

+5

PHP'yi bilmiyorum ve muhtemelen bunu asla öğrenemeyeceğim, ama bu soru üzerine tökezlediğime sevindim - açıklamanız herhangi bir dilde bit eşlemeyi uygulamanıza yardımcı olabilir :) –

+3

Güç 2 ondalıklarını bit bilge kaydırma işlemi olarak tanımlamanızı öneririm 1. define ('FLAG_1', 1 << 0); tanımlayın ('FLAG_2', 1 << 2); define ('FLAG_3', 1 << 3); define ('FLAG_4', 1 << 4); 'Bu genellikle C – AmitP

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.. 

Daha sonra ls işlevi bireysel bayrakları kontrol edebilirsiniz:

if($flags & INCLUDE_HIDDEN) { //<-- note just a single &, bitwise and 
    //$flags have INCLUDE_HIDDEN 
} 
+7

Tamsayılar yerine onaltılık sayıları kullanmanın avantajını biliyor musunuz? Sadece meraklı :) –

+0

@ AlexMorley-Finch tamamen tercih, ondalık sayıları veya hex kullanarak yürütme zamanı hiç değişmiyor gibi görünüyor, ya da –

3

Diğerleri iyi öneriler sundular, ancak bu günlerde bit maskeleri yerine ilişkisel dizileri geçmek çok daha yaygın. Çok daha okunabilir ve sadece doğru/yanlış değerler dışındaki diğer değişkenlerde geçmenize izin verir. Bunun gibi bir şey:

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

Ben de bunu böyle yapardım, fakat diğer arkadaşlarımız IDE'lerinde hiçbir "tip ipucu yok", uygun bir şekilde [doc comment] (https://en.wikipedia.org/wiki/PHPDoc) ve işlevin olmadığını söylüyorlar. [Gerekli paramlar geçmediğinde hata atmaz] (http://symfony.com/doc/current/components/options_resolver.html). İdeal olarak "adlandırılmış paramlar" php –

+0

Hi @TimoHuovinen'de mevcut olsaydı, tüm bu sorunları çözebilir - yorum için teşekkürler. Seçenekler ve varsayılanları ana hatlarıyla belirten doc yorumları eklemek, gerekiyorsa bir istisna atmak ve parametre varsayılanını tip ipuçlarına izin veren bir diziye dönüştürmek çok kolaydır. Bu senin için işe yarayacak mı? –

+0

Oh Görüyorum. Symfony OptionsResolver sınıfı daha da fazla özellik sunmak için bir adım daha ileri gider. Güzel. –

İlgili konular