Bitwise handler : gestion des bits pour gérer les droits

Description

Après la lecture de la source intéressante de malalam : http://www.phpcs.com/codes/SQUELETTE-GESTION-DROITS_48756.aspx

J'ai voulu expérimenter également la possibilité de gérer les bits.

Le contexte est le même : j'ai une classe qui peut avoir plusieurs variables avec deux états (on/off) avec le besoin de vérifier que les états se croisent.

Un utilisateur qui aurait un ensemble de droits serait le parfait exemple.

Deux choses sont traités dans ma proposition - la première étant la gestion des bits, la seconde étant le moyen d'encapsuler les propriétés (puis de les exploiter).

Regardez le code pour plus de détails.

Source / Exemple :


<?php

	/**

  • Classe de gestion des bits
  • /
abstract class byte { private $value; private $const; public function __construct($value = 0) { $this->value = $value; } public function set($flag, $value) { if ($value) { // SET BIT 1 $this->value = $this->value | $flag; } else { // SET BIT 0 $this->value = $this->value & ~$flag; } } public function get($flag) { return (($this->value & $flag) == $flag); } public function get_enum() { if (!$this->const) { $reflect = new ReflectionClass(get_class($this)); $this->const = $reflect->getConstants(); } return $this->const; } public function __get($key) { $c = $this->get_enum(); if (isset($c[$key])) { return $this->get($c[$key]); } else throw new Exception('Definition not found'); } public function __set($key, $value) { if (!is_bool($value)) throw new Exception('Boolean value expected !'); $c = $this->get_enum(); if (isset($c[$key])) { return $this->set($c[$key], $value); } else throw new Exception('Definition not found for '.$key); } public function __call($func, $args) { $action = substr($func, 0, 3); $key = strtolower(substr($func, 3)); $c = $this->get_enum(); if ($action == 'can') { if (isset($c[$key])) { return $this->get($c[$key]); } else throw new Exception('Definition not found for '.$key); } else if($action == 'set') { if (isset($c[$key])) { if (isset($args[0])) { if (is_bool($args[0])) { return $this->set($c[$key], $args[0]); } else { throw new Exception('Boolean value expected !'); } } else { return $this->set($c[$key], true); } } else throw new Exception('Definition not found for '.$key); } else throw new Exception('Undefined function '.$func); } } /**
  • Un exemple de classe
  • /
class userRights extends byte { const read = 1; // 001 const write = 2; // 010 const delete = 4; // 100 const admin = 7; // 111 } /**
  • Instanciation avec valeurs par défaul
  • /
$foo = new userRights( userRights::read | userRights::write | userRights::delete ); // MANIPULATION $foo->write = false; $foo->setRead(false); $foo->setRead(); // AFFICHAGE echo 'Read : '.$foo->read.'<hr />'; echo 'Write : '.$foo->write.'<hr />'; echo 'Delete : '.$foo->canDelete(); ?>

Conclusion :


Le premier avantage à utiliser cette méthode d'encapsultation est que vous définissez les constantes (pas de collision de noms possible) et vous exploitez directement les bits à travers des fonctions encapsulées.

Donc source utilisable par tout le monde :)

Regardez le fichier example.php pour voir comment c'est simple d'utilisation.

Codes Sources

A voir également