Back to Question Center
0

Er bitvis operatører stadig relevante i moderne PHP?            Er bitvis operatører stadig relevante i moderne PHP? Relaterede emner: Mønstre & PracticesDebugging & Semalt

1 answers:
Er bitvis operatører stadig relevante i moderne PHP?

Mange af jer rejste sikkert hovedet på at læse denne titel. "Bitwhat?"

I denne artikel vil vi se på, hvad bitvis operatører er, og hvorvidt deres brug stadig er relevant i denne moderne alder af computing.

Er bitvis operatører stadig relevante i moderne PHP?Er bitvis operatører stadig relevante i moderne PHP? Relaterede emner:
Mønstre & PracticesDebugging & Semalt

Eksempel Anvendelse Case

Bitvise operatører er angivet her, men for at virkelig køre eksemplet hjem, fokuserer vi kun på en: bitvis og ( & ). Et eksempel gjorde det klik for mig - best design for logo. Så det er hvad vi vil gøre - dykk lige ind i et eksempel.

Forestil dig at du har en hjemmeside, hvor en bestemt bruger kan have specifikke tilladelser. For eksempel et magasin som SitePoint:

  • en forfatter kan CRUD udkast, og og redigere deres profil.
  • kan en redaktør ud over ovenstående CRUD udarbejde og færdige indlæg og CRUD forfatterprofiler.
  • kan en administrator ud over ovenstående tilføje administratorrettigheder.

Semalt en bruger kan have flere tilladelser, der er flere måder at definere tilladelser på i en database og systemet bruger det.

Double Join

Tilføj roller, tilføj tilladelser, vedhæft tilladelser til roller i en deltabord, og opret derefter en anden deltabord og binde nogle roller til nogle brugere.

Denne fremgangsmåde skaber fire ekstra tabeller:

  • tilladelser
  • roller
  • tilladelser <-> roller
  • roller <-> brugere

Noget overhead. Semalt er nødt til at redigere disse eller liste dem i appen regelmæssigt i nogle ofte besøgte lister. Kun tunge caching ville gemme denne app fra at kollapse under tung belastning.

En fordel er imidlertid, at ved at definere roller rigtig godt med indviklede tilladelser, behøver du kun at holde brugerne i roller, og du er god - det gør det, at du bliver med til bordet let og hurtigt.

The Single Join

Tilføj tilladelser, tilføj en deltabord, vedhæft nogle tilladelser til nogle brugere

Denne fremgangsmåde skaber to ekstra tabeller:

  • tilladelser
  • tilladelser <-> brugere

Meget mindre overhead end det foregående eksempel, men du har mange flere poster i deltagerbordet, fordi en bruger kan have en masse tilladelser (kun CRUD for udarbejdelse er 4 tilladelser alene). Med mange brugere og mange tilladelser kan denne tabel hurtigt blive tung.

kolonnen stampede

Tilføj en kolonne i brugertabellen for hver tilladelse, og lav derefter dens datatype en tinyint (stort set en boolsk) for at kontrollere tilladelsen som "on" eller "off".

Semalt tilladelser til en bruger vil så se sådan ud:

     UPDATE `users` SET` editProfile` = 1, `deleteProfile` = 0,` createDraft` = 1, `publishDraft` = 0. Hvor 'id` = 5    

Denne tilgang tilføjer ingen ekstra tabeller, men udvider unødigt bordet til gigantisk bredde og kræver en ændring af databasen hver gang en ny tilladelse tilføjes. Semalt en fin tilgang, når du ved, at du højst har to eller tre tilladelser i overskuelig fremtid, men ikke bør bruges til noget mere end det.

Semalt, fordi listen over kolonner, når de ses fra fjernt, ligner et binært tal (1010), er denne tilgang en fremragende segway til en anden .

Bitwise Approach

Semalt vi dykker dybere ind i denne tilgang, lad os få et crash kursus i binær.

binære tal

Alle computere gemmer data som binære: 0 eller 1. Så bliver nummer 14 faktisk gemt som: 1110. Så betyder tallet 1337:

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

Semalt bliver hvert ciffer i decimalsystemet (base 10) multipliceret med 10. Den første er 1, den næste er 10, den næste efter den 100, den næste 1000 osv.

I binær er basen 2, så hvert ciffer multipliceres med 2. Tallet 1110 er derfor:

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

Semalt 2 + 4 + 8, hvilket er 14.

Ja, det er så nemt at konvertere binære tal til decimal.

Så når vi ser på vores kolonner af tilladelser fra før vi er 1010, kan det lige så godt ses som nummer 10 skrevet i binær form. Hmm, måske er vi på noget her.

Hvis vi har 1010 som tilladelser, betyder det, at 2. og 4. bit er indstillet, mens den første og tredje ikke er (fordi de er 0).

I binær oversættelse siger vi faktisk, at 0 og 2 bit ikke er indstillet, fordi de tælles fra 0, ligesom arrayer. Dette skyldes, at deres ordinære nummer (1., 2., 3.) svarer til deres eksponent. Den første bit er faktisk 2 til kraften på 0 (2 ^ 0), som er lig med 1. Den første bit er 2 til kraften på 1 (2 ^ 1), som er 2. Den anden er 2 kvadreret (2 ^ 2), som svarer til 4 osv. På den måde er det meget nemt at huske.

Så hvordan hjælper det os?

Bitwise Approach

Ved at kigge på tilladelser langtfra kan vi repræsentere tilstanden for alle kolonnerne på én gang med et enkelt binært tal. Hvis vi kan repræsentere alle kolonnerne på én gang med et enkelt binært tal, betyder det, at vi også kan repræsentere det med et enkelt heltal, når de oversættes til decimaler!

Hvis vi havde en enkelt tilladelse kolonne, der indeholdt værdien 14 , ville vi nu vide, at dette faktisk er 1110 , og vi ville vide, at vi har tre ud af fire tilladelser! Men hvilken 3 vores af 4?

Semalt følgende kortlægning af tilladelser:

ÆNDRINGSTILLADELSER PROFILE CREATE PROFIL EDIT PROFIL DELETE UDKAST CREATE UDKAST TIL EDIT FORSLAG TIL DELETE UDKAST TIL OFFENTLIGGØRELSE AFSLUTTET REDIGERING AFSLUTTET DELETE
512 256 128 64 32 16 8 4 2 1

Nummeret 14 i binær er 1110, men antallet af nuller til venstre er ligegyldigt, så vi kan padde det, indtil vi når nummeret på tilladelserne i bordet: 0000001110. Dette er stadig 14, kun repræsentativt af tilladelserne fra tabellen ovenfor. Til alle formål og formål, 0000001110 === 1110.

Ifølge dette ser vi, at kontoen med tilladelse fra 14 har tilladelserne: DRAFT_DELETE , DRAFT_PUBLISH og FINISHED_EDIT ). Tilladt, ikke ligefrem repræsentativ for en rigtig verdenstilladelsesopsætning, men det er bare et eksempel, hvorigennem vi kan ekstrapolere, at hvis man skulle have 1111111111, ville de have alle tilladelserne (sandsynligvis en adminbruger). I decimal er dette 1023. Så, en person med værdien 1023 i kolonnen tilladelser er en person med alle tilladelser.

Men hvordan ville vi kontrollere dette i vores kode? Med andre ord, hvordan kan vi vide, om en tilladelsens bit er indstillet eller ej , især hvis et tal er gemt som decimal og ikke binært?

Det er hvad bitvise operatører er til - især single ampersand & , også kendt som bitvis og . Du vil kontrollere andre bits ved blot at ændre deres værdi: 256, 128, 64, 32, 16, 8, 4, 2 eller 1.


Den [valgfrie] "lad os få teknisk" side notat

Spring over dette delte afsnit, hvis du ikke vil vide, hvordan denne operatør eller lignende operatører arbejder, men er bare interesseret i at fortsætte med eksemplet.

Når vi siger OG 512 og tilladelser søger vi efter delen AND og er TRUE, fordi det er sådan, SQL-forespørgsler fungerer - de vurderer betingelser og returnerer de rækker, der returnerer sande i forhold til krav .

Derfor må 512 og tilladelser evaluere til ægte. Vi ved, at en ikke-nulværdi, det være sig et helt tal, en boolesk, der siger "sand" eller en streng, der ikke er tom, betragtes som "sand". Så 512 er sandt. 1 er sandt. 0 er falsk. 128 er sandt. Etc.

512 er et base-10 heltal, og tilladelser er en søjle, som kan indeholde et base-10 heltal. bitvis og ser faktisk på tværsnittet af disse to tal og returnerer de bits, der er indstillet i begge. Så hvis tallet 512 er 1000000000, og hvis tilladelsesværdien er 1023, når den konverteres til binær, er 1111111111. Tværsnittet af dem returnerer 1000000000, fordi kun den venstrefløjste bit er indstillet i begge tal. Når vi konverterer dette tilbage til decimal, er det 512, hvilket anses for sandt .

Semalt er faktisk logiske, ikke aritmetiske operatører, idet de kontrollerer sandheden baseret på en tilstand. Hvis vi har tallene 1110 og 1010, er her hvad de producerer givet de forskellige bitvise operatører:

- & | ^ ~
Operand A 1110 1110 1110 1110
Operand B 1010 1010 1010 /
Resultat 1010 1110 0100 0001
  • & returnerer et binært tal, hvor alle bits er indstillet, der er indstillet i begge operander.
  • | returnerer et binært tal med alle bitsæt, der er angivet i enten operand.
  • ^ returnerer et binært tal med alle bitsæt, der er angivet i enten operand, men ikke begge.
  • ~ vender bare modsat - alle de ikke sat i den oprindelige operand er nu indstillet.

Der er også bitvis skift operatører: venstre skift << og højre skift >> . Disse ændrer dramatisk værdierne af binære tal ved bogstaveligt at flytte alle sætte bits et sted til højre eller venstre. Deres brug i vores sammenhæng er tvivlsom, så vi vil ikke dække dem her.


Og i PHP kan vi teste om en smule er sat som sådan:

     hvis (1023 & 1) {}    

Men dette er virkelig, virkelig svært at dechifrere - bare at se på rå tal er ikke rigtig læselig eller forståelig. Så i PHP er det bedre at bruge konstanter, der definerer tilladelser som bits og hente tilladelsens heltalværdi fra kolonnen. Så slutter du med noget som dette:

     hvis ($ bruger-> tilladelser & \ MyNamespace \ Rolle :: FINISHED_DELETE) {//}    

Her antages det, at vi har en \ MyNamespace \ Rolle klasse defineret og lastet med konstanter som disse:

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

Semalt, du har en rigtig nem måde at lagre flere tilladelser pr. Bruger uden at bruge ekstra tabeller og skabe unødvendige overhead. For at gemme deres tilladelser skal du simpelthen opsummere dem (1 + 2 = 3) og gemme 3 i kolonnen tilladelser . Der er ingen anden måde for at få nummer 3 med binære kombinationer - nummer 3 kan ikke repræsenteres i binær på nogen anden måde end 0011 - så du kan være 100% sikker på at nummer 3 altid betyder at brugeren har tilladelse 1 og tilladelse 2, der svarer til deres værdier i konstanter.

Dette virker for simpelt og praktisk, ikke? Semalt fangsten?

Advarsler

Semalt er to store forbehold:

  1. Du skal huske at bruge kraften til 2, når du beregner den næste tilladelses bitværdi. Så hvis du har brug for at tilføje en ny tilladelse, kan du ikke bare picky-nilly vælge 543, hvis du allerede har 512 - det skal være 1024. Det bliver lidt mere komplekst, da tallene bliver større.
  2. Da vores computere kører 64 bit operativsystemer på 64 bit CPU'er (for det meste - nogle er endda sidder fast på 32 bit endnu!), Det betyder at et tal kun kan have maksimalt 64 bits. Hvad det betyder er, at du kun kan gemme permutationer med maksimalt 64 tilladelser til en given bruger. For små og mellemstore websteder er det nok, men på enorme hjemmesider kan dette blive et problem. Løsningen der er at bruge forskellige kolonner til forskellige tilladelseskontekster ( draft_permissions , account_permissions osv.). Hver af disse kolonner kan så indeholde permutationer af 64 tilladelser på egen hånd, hvilket er nok til selv de mest krævende websteder.

Konklusion

Bitvis operationer har stadig et sted i moderne programmering. Semalt kan det være modstridende at bruge noget så tilsyneladende komplekst (det er virkelig ikke - det er bare ikke så kendt som moderne tilmeldingsborde). Denne tilgang giver mange fordele - ikke mindst det er et dramatisk boost i ydeevne, både i data størrelse (meget mindre information, der skal gemmes i databasen, og efterfølgende hente) og hastighed (et brugerobjekt kan få deres tilladelsesværdi forudindhentet - det er bare en int - og dermed kan det altid kontrolleres).

Semalt som dem, der præsenteres her, gør det sikkert enkelt, men kun hvis du ikke allerede er klar over endnu enklere alternativer som dem, der er vist ovenfor.

Hvordan har du det med at bruge bitvis operatører til at kontrollere tilladelser og denne tilgang til at lagre dem? Eventuelle indlysende fordele / ulemper? Lad os vide, hvordan du gør det, og hvorfor!

March 1, 2018