Uma forma muito elegante de armazenar uma série de regras, utilizando um só valor, é utilizando os Bitwise Operators.
O PHP faz isso a um bom tempo já, e um bom exemplo é a função error_reporting, onde podemos utilizar uma série de regras para denominar quais os erros devem ser reportados.
error_reporting(E_ERROR | E_WARNING);
No exemplo acima, foi denominado que somente os tipos de erro E_ERROR e E_WARNING devem ser reportados. Se quiséssemos que o tipo de erro E_PARSE fosse reportado também, bastariamos adiciona-lo na regra:
error_reporting(E_ERROR | E_WARNING | E_PARSE);
Mas como isso funciona?
Utilizando como exemplo, essas contantes do PHP contém os seguintes valores:
E_ERROR 1 E_WARNING 2 E_PARSE 4
O operador | é uma operação “Or” inclusiva, o que indica que, todo bit que estiver presente em A ou B, será utilizado.
0001 ou 0010 = 0011
Podemos verificar o valor em binário de cada uma das constantes, utilizando a função printf:
$ php -r 'printf("%04b", E_ERROR);'
0001
$ php -r 'printf("%04b", E_WARNING);'
0010
$ php -r 'printf("%04b", E_PARSE);'
0100
Portanto, voltando ao exemplo inicial da função error_reporting, temos:
E_ERROR | E_WARNING
E se fizermos a operação, obteremos 0011, vejamos:
$ php -r 'printf("%04b", E_ERROR | E_WARNING);'
0011
E como verificamos se E_ERROR esta contido em E_ERROR | E_WARNING?
Simples. Basta utilizar o operador &, que realiza uma operação “And”, onde somente são utilizados os bits presentes em A e B.
(E_ERROR | E_WARNING) & E_ERROR
Traduzindo em bits, ficaria:
0011 e 0001 = 0001
Veja que o resultado tem o mesmo valor de B, e é assim que funciona, basta comparar E_ERROR com o resultado de (E_ERROR | E_WARNING) & E_ERROR.
Agora em PHP, já que um exemplo vale mais que mil palavras:
if (E_ERROR == ((E_ERROR | E_WARNING) & E_ERROR))
{
echo 'E_ERROR presente nas regras';
}
Criando a sua própria série de regras
Imagine uma situação, onde você possui um sistema com vários usuários, e cada usuário pode conter as permissões P_READ (leitura), P_WRITE (escrita), P_REMOVE (remoção).
Criamos então, uma permissão “base”, chamada P_NONE (nada).
define('P_NONE', 100);
E em seguida, as outras permissões:
define('P_READ', P_NONE << 1);
define('P_WRITE', P_NONE << 2);
define('P_REMOVE', P_NONE << 3);
Logo, podemos criar uma regra para um usuário:
$mode = P_READ | P_WRITE;
E armazena-la em um banco de dados. Aqui utilizei um campo int, em um banco de dados MySQL.
mysql_query("update users set mode = $mode where id = $id");
Posteriormente, você pode listar os usuários que tem permissão para escrita:
$mode = P_WRITE;
$users = mysql_query("select * from users where (mode & $mode) = $mode");
Para verificar com PHP:
if (P_READ == ($user->mode & P_READ))
{
echo 'Este usuário possui permissão para leitura.';
}
Conclusão
Você pode especificar várias e várias regras, utilizando apenas um valor, uma variável ou um campo no banco de dados. Basta utilizar alguns bits e operações lógicas.
Para maiores informações sobre os Bitwise Operators do PHP, basta acessar a URL: