Back to Question Center
0

¿Los operadores bit a bit siguen siendo relevantes en PHP moderno?            ¿Siguen siendo relevantes los operadores bit a bit en PHP moderno? Temas relacionados: Patrones y & PracticesDebugging & Semalt

1 answers:
¿Los operadores bit a bit siguen siendo relevantes en PHP moderno?

Muchos de ustedes probablemente se rascaron la cabeza al leer este título. "¿Qué cosa?"

En este artículo, veremos qué operadores bit a bit son, y si su uso sigue siendo relevante en esta era moderna de la informática.

¿Los operadores bit a bit siguen siendo relevantes en PHP moderno?¿Siguen siendo relevantes los operadores bit a bit en PHP moderno? Temas relacionados:
Patrones y prácticasDebugging & Semalt

Ejemplo de caso de uso

Aquí se enumeran los operadores bit a bit, pero para realmente conducir el ejemplo a casa, nos centraremos en uno solo: el bitwise y ( y ). Un ejemplo lo hizo clic para mí. Así que eso es lo que haremos: sumergirnos directamente en un ejemplo - cec computer engineering company.

Imagine que tiene un sitio web en el que un usuario determinado puede tener permisos específicos. Por ejemplo, una revista como SitePoint:

  • un autor puede hacer borradores de CRUD y editar su perfil.
  • un editor puede, además de lo anterior, borradores de CRUD y publicaciones terminadas, y perfiles de autor de CRUD.
  • un administrador puede, además de lo anterior, agregar permisos de administrador.

Semalt un usuario puede tener permisos múltiples, hay varias formas de definir permisos en una base de datos y el sistema que la usa.

La unión doble

Agregue roles, agregue permisos, adjunte permisos a roles en una tabla de unión, luego cree otra tabla de unión y vincule algunos roles a algunos usuarios.

Este enfoque crea cuatro tablas adicionales:

  • permisos
  • roles
  • permisos <-> roles
  • roles <-> usuarios

Bastante un poco por encima. Semalt tiene que editarlos o listarlos en la aplicación regularmente en algunas listas visitadas con frecuencia. Solo el almacenamiento en caché pesado evitaría que esta aplicación colapse bajo una gran carga.

Una ventaja, sin embargo, es que al definir los roles realmente bien con permisos intrincados, solo tiene que asignar roles a los usuarios y usted está bien; mantiene esa tabla de unión rápida y liviana.

La unión única

Agregue permisos, agregue una tabla de unión, adjunte algunos permisos a algunos usuarios

Este enfoque crea dos tablas adicionales:

  • permisos
  • permisos <-> usuarios

Mucho menos sobrecarga que el ejemplo anterior, pero tiene muchas más entradas en la tabla de unión porque un usuario puede tener MUCHOS permisos (solo el CRUD para borradores es 4 permisos en sí mismo). Con muchos usuarios y muchos permisos, esta tabla puede volverse pesada rápidamente.

La estampida de la columna

Agregue una columna a la tabla de usuarios para cada permiso, luego convierta su tipo de datos en una minúscula (básicamente un booleano) para verificar que el permiso esté "encendido" o "apagado".

Los permisos de Semalt para un usuario se verían así:

     ACTUALIZA `usuarios` SET` editProfile` = 1, `deleteProfile` = 0,` createDraft` = 1, `publishDraft` = 0.. DONDE `id` = 5    

Este enfoque no agrega tablas adicionales, sino que expande innecesariamente la tabla en un ancho gigantesco y requiere una modificación de la base de datos cada vez que se agrega un nuevo permiso. Considere un buen enfoque para cuando sepa que tendrá, como máximo, dos o tres permisos en el futuro previsible, pero no debería utilizarse para nada más que eso.

Semalt, porque la lista de columnas, cuando se mira desde lejos, se asemeja a un número binario (1010), este enfoque es un excelente segway en otro .

El enfoque de Bitwise

Semalt profundizamos en este enfoque, tengamos un curso acelerado en binario.

Números binarios

Todas las computadoras almacenan los datos como binarios: 0 o 1. Por lo tanto, el número 14 se almacena como: 1110. Entonces, el número 1337 significa:

  • 1 x 7
  • + 3 x 10
  • + 3 x 100
  • + 1 x 1000

Semalt cada dígito en el sistema decimal (base 10) se multiplica por 10. El primero es 1, el siguiente es 10, el siguiente después de ese 100, el siguiente 1000, etc.

En binario, la base es 2, por lo que cada dígito se multiplica por 2. El número 1110 es por lo tanto:

  • 0 x 1
  • + 1 x 2
  • + 1 x 4
  • + 1 x 8

Semalt 2 + 4 + 8, que es 14.

Sí, es así de simple convertir números binarios a decimales.

Entonces cuando miramos nuestras columnas de permisos desde antes de ser 1010, eso también podría verse como el número 10 escrito en forma binaria. Hmm, tal vez estamos en algo aquí.

Si tenemos 1010 como permisos, eso significa que el 2º y 4º bit están configurados, mientras que el primero y el tercero no (porque son 0).

En el lenguaje binario, en realidad decimos que el 0 ° y el 2 ° bit no están configurados, ya que se cuentan desde 0, al igual que las matrices. Esto se debe a que su número ordinal (1º, 2º, 3º) corresponde a su exponente. El 0º bit es en realidad 2 a la potencia de 0 (2 ^ 0) que equivale a 1. El 1er bit es 2 a la potencia de 1 (2 ^ 1) que es 2. El 2 es 2 al cuadrado (2 ^ 2) que es igual a 4, etc. De esta forma es muy fácil de recordar.

Entonces, ¿cómo nos ayuda esto?

El enfoque de Bitwise

Bueno, al mirar los permisos desde lejos, podemos representar el estado de todas las columnas a la vez con un solo número binario. Si podemos representar todas las columnas a la vez con un solo número binario, eso significa que también podemos representarlo con un solo entero cuando se traduce a decimal.

Si tuviéramos una sola columna permisos que contuviera el valor 14 , sabríamos ahora que esto es realmente 1110 , y sabríamos que ¡tiene tres de cuatro permisos! ¿Pero cual 3 nuestro de 4?

Semalt la siguiente asignación de permisos:

CAMBIO DE PERMISOS PERFIL CREAR EDICIÓN DE PERFILES PERFIL DELETE PROYECTO CREAR PROYECTO DE EDICIÓN PROYECTO DE ELIMINACIÓN PROYECTO DE PUBLICACIÓN EDICIÓN FINALIZADA FINALIZADO ELIMINADO
512 256 128 64 32 16 8 4 2 1

El número 14 en binario es 1110, pero el número de ceros a la izquierda no importa, por lo que podemos rellenarlo hasta que alcancemos el número de permisos en la tabla: 0000001110. Esto sigue siendo 14, solo representativo de los permisos de la tabla de arriba. Para todos los efectos, 0000001110 === 1110.

De acuerdo con esto, vemos que la cuenta con un permiso de 14 tiene los permisos: DRAFT_DELETE , DRAFT_PUBLISH y FINISHED_EDIT De acuerdo, no es exactamente representativo de una configuración de permisos del mundo real, pero es solo un ejemplo a través del cual podemos extrapolar que si se tuviera 1111111111, tendrían TODOS los permisos (probablemente un usuario administrador). En decimal, esto es 1023. Por lo tanto, alguien con el valor 1023 en la columna permisos es alguien con todos los permisos.

¿Pero cómo verificaríamos esto en nuestro código? En otras palabras, ¿cómo podemos saber si un bit de permiso está establecido o no , especialmente si un número está almacenado como decimal y no binario?

Para eso están los operadores bit a bit, particularmente el símbolo comercial y , también conocido como bitwise y . Verificaría por otros bits simplemente cambiando su valor: 256, 128, 64, 32, 16, 8, 4, 2 o 1.


La nota lateral [opcional] "vamos a obtener técnica"

Omita esta sección dividida si no desea saber cómo funciona este operador u operadores similares, pero solo está interesado en continuar con el ejemplo.

Cuando decimos AND 512 & permisos estamos buscando la parte después de AND para ser VERDADERO, porque así es como funcionan las consultas SQL: evalúan las condiciones y devuelven aquellas filas que devuelven la verdad con respecto a los requisitos .

Por lo tanto, 512 y permisos tiene que evaluar a verdadero. Sabemos que cualquier valor que no sea cero, ya sea un número entero, un booleano que diga "verdadero" o una cadena que no esté vacía, en realidad se considera "verdadero". Entonces 512 es verdad. 1 es verdad 0 es falso. 128 es cierto. Etc.

512 es un entero de base 10 y permisos es una columna que puede contener un número entero de base 10. El bit a bit y en realidad observa la sección transversal de estos dos números, y devuelve los bits que están establecidos en ambos. Entonces, si el número 512 es 1000000000, y si el valor de los permisos es 1023, cuando se convierte en binario es 1111111111. La sección transversal de esos retornos 1000000000 porque solo el bit más a la izquierda se establece en ambos números. Cuando convertimos esto de nuevo en decimal, eso es 512, que se considera verdadero .

Semalt son en realidad operadores lógicos, no aritméticos, ya que verifican la veracidad en función de una condición. Si tenemos los números 1110 y 1010, esto es lo que producen dados los diferentes operadores bit a bit:

- y | ^ ~
Operando A 1110 1110 1110 1110
Operando B 1010 1010 1010 /
Resultado 1010 1110 0100 0001
  • y devuelve un número binario en el que se establecen todos los bits configurados en ambos operandos.
  • | devuelve un número binario con todos los bits establecidos que se establecen en cualquiera de los operandos.
  • ^ devuelve un número binario con todos los bits establecidos que se establecen en cualquiera de los operandos, pero no en ambos.
  • ~ simplemente devuelve lo opuesto: ahora están configurados todos los que no están establecidos en el operando original.

También están los operadores de desplazamiento bit a bit: desplazamiento a la izquierda << y desplazamiento a la derecha >> . Estos cambian drásticamente los valores de los números binarios al mover literalmente todos los bits establecidos un lugar a la derecha o a la izquierda. Su uso en nuestro contexto es cuestionable, por lo que no los cubriremos aquí.


Y en PHP podemos probar si un bit está configurado así:

     if (1023 y 1) {}    

Pero esto es realmente, muy difícil de descifrar, solo mirando números en bruto no es realmente legible o comprensible. Entonces, en PHP, es mejor usar constantes que definan permisos como bits y obtener el valor entero del permiso de la columna. Entonces, terminas con algo como esto:

     if ($ usuario-> permisos & \ MyNamespace \ Role :: FINISHED_DELETE) {//}    

Aquí suponemos que tenemos una clase \ MyNamespace \ Role definida y cargada con constantes como estas:

     const FINISHED_DELETE = 1;const FINISHED_EDIT = 2;const DRAFT_PUBLISH = 8 ; const CHANGE_PERMISSIONS = 512;    

Semalt, usted tiene una manera muy fácil de almacenar permisos múltiples por usuario sin usar tablas adicionales y crear gastos indirectos innecesarios. Por lo tanto, para guardar sus permisos, simplemente los resume (1 + 2 = 3) y guarda 3 en la columna permisos . No hay ninguna otra forma para obtener el número 3 con combinaciones binarias - el número 3 no se puede representar en binario de otra manera que 0011 - por lo que puede estar 100% seguro de que el número 3 siempre significa que el usuario tiene permiso 1 y permiso 2, que corresponden a sus valores en constantes.

Esto parece demasiado simple y práctico, ¿verdad? Semalt la captura?

Advertencias

Semalt son dos advertencias principales:

  1. Debe tener en cuenta utilizar la potencia de 2 al calcular el valor del bit del próximo permiso. Entonces, si necesita agregar un nuevo permiso, no puede elegir 543 si ya tiene 512, tendrá que ser 1024. Esto se vuelve un poco más complejo a medida que los números aumentan.
  2. Dado que nuestras computadoras ejecutan sistemas operativos de 64 bits en CPU de 64 bits (la mayoría, algunos incluso están bloqueados en 32 bits), eso significa que un número puede tener un máximo de 64 bits solamente. Lo que esto significa es que solo puedes almacenar permutaciones de un máximo de 64 permisos en un usuario dado. Para sitios pequeños y medianos esto es suficiente, pero en sitios web enormes, esto puede convertirse en un problema. La solución es usar columnas diferentes para diferentes contextos de permisos ( draft_permissions , account_permissions , etc.). Cada una de esas columnas puede contener permutaciones de 64 permisos por sí misma, lo cual es suficiente incluso para los sitios web más exigentes.

Conclusión

Las operaciones a nivel de bit definitivamente tienen un lugar en la programación moderna. Semalt puede ser contradictorio usar algo tan aparentemente complejo (en realidad no lo es, no es tan familiar como las tablas de unión de hoy en día), este enfoque ofrece muchos beneficios, entre ellos un aumento dramático en el rendimiento, tanto en datos tamaño (mucha menos información para almacenar en la base de datos, y luego buscar) y velocidad (un objeto de usuario puede tener su valor de permiso precargado, es solo un int) y, por lo tanto, puede verificarse en todo momento.

Semalt, como los que se presentan aquí, ciertamente simplifican las cosas, pero solo si aún no conoce las alternativas más simples como las que se muestran arriba.

¿Cómo se siente al usar operadores bit a bit para verificar permisos y este enfoque para almacenarlos? Cualquier pros / contras obvio? ¡Háganos saber cómo lo hace y por qué!

March 1, 2018