2017-10-18 5 views
0

Je n'ai jamais travaillé avec les bitmasks, étant donné tout ce que PHP m'offre comme alternatives et à quel point les manipulations de bits ont toujours été compliquées, j'ai passé cette partie du manuel il ya des années.Combiner plusieurs masques de bits

Mais récemment, la curiosité me suis jeté un œil et la première chose que j'ai été demander à Google et il m'a amené à this topic

Il était assez facile à comprendre, mais peut-être l'exemple obtenu le meilleur de moi parce que quand j'ai essayé de faire quelque chose de différent, cela n'a pas fonctionné.

Un scénario similaire ici je, peut-être, utiliser bitmasks serait une validation de type de données:

class Types { 

    const STRING = 1; 
    const INTEGER = 2; 
    const FLOAT = 4; 
    const BOOLEAN = 8; 
    const ARRAYS = 16; 
    const OBJECT = 32; 

    protected $flags = 0; 

    public function __construct($flags) { 
     $this -> flags = $flags; 
    } 

    function validate($data) { 
     if ($this -> flags & self::STRING && ! is_string($data)) return 1; // not string 

     if ($this -> flags & self::INTEGER && ! is_int($data)) return 2; // not integer 

     if ($this -> flags & self::FLOAT && ! is_float($data)) return 3; // not float 

     if ($this -> flags & self::BOOLEAN && ! is_bool($data)) return 4; // not boolean 

     if ($this -> flags & self::ARRAYS && ! is_array($data)) return 5; // not array 

     if ($this -> flags & self::OBJECT && ! is_object($data)) return 6; // not object 

     return $data; 
    } 
} 

L'exécution de ce code comme:

$types = new Types(Types::STRING); 

var_dump($types -> validate('Stack Overflow')); 

Je vois la chaîne d'entrée car aucun des conditions ont été satisfaites. Mais si je change les drapeaux à comme dans Types::STRING | Types::INTEGER, en espérant que des chaînes ou des entiers seraient acceptés, je reçois en sortie à partir de la deuxième return déclaration

Tous les autres exemples que j'ai vu, ici et dans blogs "aléatoires", utilisaient else déclarations en cas d'échec de la condition, ce qui est la chose évidente à faire (ou inverser l'opérateur - mais c'est à côté du point), mais je ne crois pas honnêtement que si je voulais faire ce pseudo -code de travail - dans le sens de tester si les données d'entrée sont chaîne ou entier, float ou tableau et ainsi de suite - je devrais dupliquer le code de vérification N fois, un pour chaque type que je testerais

Quelqu'un pourrait-il clarifier un peu pour moi?

+0

L'idée de tester contre plusieurs types échoue dès que vous «revenez» et sautez ainsi hors de toute la fonction im médiatement après la première validation échoue. Tout d'abord, spécifiez le résultat attendu lorsque vous testez «Stack Overflow» par rapport à «string or integer». Vous effectuez des tests _negative_ ici, alors que pensez-vous que la fonction retournera réellement en fonction du fait que c'est une chaîne, mais pas un nombre entier? Que voulez-vous qu'il retourne si la valeur testée n'était ni une chaîne ni un nombre entier? – CBroe

+0

Je savais honnêtement que je ne devais pas utiliser 'return' ou même' exit' car cela interromprait le flux mais là encore je n'avais pas la moindre idée de ce que je faisais spécifiquement à ce sujet. Quoi qu'il en soit, je m'attendrais à ce que les données d'entrée soient retournées si elles sont de l'un des types indiqués par l'un des masques et stoppent le processus autrement, que ce soit en quittant le flux ou en retournant 'FALSE'. Pour l'instant je suis en train d'expérimenter – user5613506

Répondre

0

Par exemple, si vous voulez vérifier le résultat de la validité où

<?php 
header('content-type: text/plain'); 
$amount = rand(1,9); 
$result = $amount/rand(1,9); 
echo "result=$result\ntype=" . gettype($result) . "\n"; 
echo 'validate = ' . validate($result) . "\n"; 
if (validate($result) & 0b00000110){ 
    echo "result is NUMERIC"; 
} 
elseif (validate($result) & 0b00001000){ 
    echo "result is Boolean\n"; 
} 
elseif (validate($result) & 0b11000001){ 
    echo "result is INVALID "; 
} 

function validate($data){ 
    $types = array(
    'string'=>1, 
    'integer'=>2, 
    'double' =>4, 
    'boolean'=>8, 
    'array'=>16, 
    'object'=>32, 
    'resource'=>64, 
    'NULL'=>128, 
    'unknown type'=>256); 
    return $types[gettype($data)]; 
} 
?> 

Pour plus de clarté, le tableau de types pourrait aussi être:

$types = array(
    'string' =>0b000000001, 
    'integer' =>0b000000010, 
    'double' =>0b000000100, 
    'boolean' =>0b000001000, 
    'array' =>0b000010000, 
    'object' =>0b000100000, 
    'resource'=>0b001000000, 
    'NULL' =>0b010000000, 
    'unknown type'=>0b100000000); 

Exemples de réponses:

result=7 
type=integer 
validate = 2 
result is NUMERIC 

result=0.14285714285714 
type=double 
validate = 4 
result is NUMERIC