2012-08-09 12 views
60

No estoy seguro de si la máscara de bits es el término correcto. Me explico:¿Cómo implementar una máscara de bits en php?

en PHP, la función error_reporting se puede llamar varias maneras:

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

Tengo la máscara de bits plazo a partir de la página php.net here

De todos modos el punto de esto es, Implementé un método SIMPLE llamado ls que devuelve el contenido de un directorio.

Esta función toma 3 args ... ($ include_hidden = false, $ return_absolute = false, $ ext = false)

Así que cuando llama a la función, me puse como quiero los resultados. Si quiero los resultados vuelven a directorios ocultos, si quiero nombres base únicamente etc.

así que cuando llama a la función que estoy escribiendo

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

pensé que sería mucho más fácil de leer si tan sólo pudiera Indica cómo quiero que se devuelvan los datos?

así que algo como:

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

etc ...

¿cómo iba a implementar esto en términos de pruebas, que las banderas han sido llamados?

+1

bien pedido. KISS – Nico

Respuesta

121

Es bastante simple en realidad. Primero, un poco de código para demostrar cómo se puede implementar. Si usted no entiende nada de lo que este código está haciendo o cómo funciona, no dude en hacer preguntas adicionales en los comentarios:

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


Debido a que las banderas son enteros, en una plataforma de 32 bits define hasta 32 banderas. En una plataforma de 64 bits, es 64. También es posible definir los indicadores como cadenas, en cuyo caso el número de indicadores disponibles es más o menos infinito (dentro de los límites de los recursos del sistema, por supuesto). Así es como funciona en formato binario (reducido a enteros de 8 bits para simplificar).

FLAG_1 
Dec: 1 
Binary: 00000001 

FLAG_2 
Dec: 2 
Binary: 00000010 

FLAG_3 
Dec: 4 
Binary: 00000100 

// And so on... 

Cuando combina las banderas para pasarlas a la función, usted O ellas juntas. Vamos a echar un vistazo a lo que sucede cuando se pasa FLAG_1 | FLAG_3

00000001 
| 00000100 
= 00000101 

Y cuando queremos ver que se colocó banderas, usted y la máscara de bits con la bandera. Por lo tanto, vamos a echar el resultado anterior y ver si se estableció FLAG_3:

00000101 
& 00000100 
= 00000100 

...obtenemos el valor de la bandera de espalda, un número entero distinto de cero - pero si vemos Si se ha programado :

00000101 
& 00000010 
= 00000000 

... obtenemos cero. Esto significa que puede simplemente evaluar el resultado de la operación Y como un booleano al verificar si se pasó el valor.

+5

Por lo tanto, las operaciones básicas en bits son: '$ flags & FLAG_1' - comprueba si FLAG_1 está configurado , '$ banderas | FLAG_1' - establece FLAG_1, '$ flags & ~ FLAG_1' - desactiva FLAG_1,' ~ $ flags' - invierte las banderas –

+5

No conozco PHP y probablemente nunca lo aprenda, pero me alegro de haber tropezado con esta pregunta: su explicación puede ayudar a cualquiera a implementar el mapeo de bits en cualquier idioma :) –

+3

Yo recomendaría definir los decimales de potencia 2 como una operación de cambio de bits de 1. 'define ('FLAG_1', 1 << 0); define ('FLAG_2', 1 << 2); define ('FLAG_3', 1 << 3); define ('FLAG_4', 1 << 4); 'Así es como generalmente se hace en 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.. 

A continuación, puede comprobar si hay banderas individuales en su función ls:

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

¿Conoces una ventaja de usar números hexadecimales en lugar de enteros? Sólo curiosidad :) –

+0

@ AlexMorley-Finch parece puramente de preferencia, usando decimales o hex no parece cambiar el tiempo de ejecución en absoluto, ya sea –

3

Los otros han ofrecido buenas sugerencias, pero en estos días es mucho más común pasar matrices asociativas en lugar de máscaras de bits. Es mucho más legible y le permite pasar otras variables que no sean solo valores verdaderos/falsos. Algo como esto:

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

Yo solía hacerlo de esta manera también, pero compañeros compañeros se quejan de que no hay "sugerencias tipográficas" en sus IDE, no hay comentarios [doc] adecuados (https://en.wikipedia.org/wiki/PHPDoc) y la función no [arroja errores cuando no se pasan los parámetros necesarios] (http://symfony.com/doc/current/components/options_resolver.html). Idealmente, "params con nombre" resolvería todos estos problemas si existieran en php –

+0

Hola @TimoHuovinen, gracias por el comentario. Es fácil agregar comentarios de documentos que describan las opciones y los valores predeterminados, genere una excepción si es necesario y establezca el parámetro de forma predeterminada en una matriz que permita la sugerencia de tipo. ¿Funcionará para ti? –

+0

Oh, ya veo. La clase Symfony OptionsResolver va un paso más allá para ofrecer aún más funciones. Guay. –

Cuestiones relacionadas