Back to Question Center
0

Adakah Operator Bitwise Masih relevan dalam PHP Moden?            Adakah Operator Bitwise Masih Berkaitan dalam PHP Moden? Topik Berkaitan: Corak & AmalanDebugging & Semalt

1 answers:
Adakah Operator Bitwise Masih relevan dalam PHP Moden?

Ramai daripada anda mungkin tercalar kepala anda membaca tajuk ini. "Bitwhat?"

Dalam artikel ini, kita akan melihat apa operator bitwise, dan sama ada atau tidak penggunaannya masih relevan dalam zaman moden ini pengkomputeran.

Adakah Operator Bitwise Masih relevan dalam PHP Moden?Adakah Operator Bitwise Masih Berkaitan dalam PHP Moden? Topik Berkaitan:
Corak & AmalanDebugging & Semalt

Contoh Penggunaan Kes

Pengendali bitwise disenaraikan di sini, tetapi untuk benar-benar memandu rumah contoh, kami akan memberi tumpuan kepada hanya satu: bitwise dan ( & ). Satu contoh membuatnya klik untuk saya. Jadi itulah yang akan kita lakukan - menyelam terus ke dalam contoh.

Bayangkan anda mempunyai laman web di mana pengguna tertentu boleh mempunyai keizinan tertentu. Sebagai contoh, majalah seperti SitePoint:

  • penulis boleh membuat draf CRUD, dan mengedit profil mereka.
  • seorang editor boleh, sebagai tambahan kepada di atas, Draf CRUD dan jawatan selesai, dan profil pengarang CRUD.
  • pentadbir boleh, sebagai tambahan kepada di atas, menambah kebenaran pentadbir.

Semalt pengguna boleh mempunyai beberapa kebenaran, terdapat beberapa cara mendefinisi keizinan dalam pangkalan data dan sistem menggunakannya.

Sertai Double

Tambah peranan, tambahkan keizinan, lampirkan keizinan pada peranan dalam jadual gabungan, kemudian buat jadual bergabung lain dan sambungkan beberapa peranan kepada beberapa pengguna.

Pendekatan ini menghasilkan empat jadual tambahan:

  • kebenaran
  • peranan
  • kebenaran <-> peranan
  • peranan <-> pengguna

agak sedikit overhead. Semalt perlu menyuntingnya atau menyenaraikannya dalam aplikasi secara berkala dalam beberapa senarai yang sering dikunjungi. Hanya caching berat akan menyelamatkan aplikasi ini daripada runtuh di bawah beban berat.

Namun, satu kelebihan adalah dengan menentukan peranan yang sangat baik dengan keizinan yang rumit, anda hanya perlu melekatkan pengguna ke dalam peranan dan anda baik - ia memastikan bahawa ia menyatukan cahaya jadual dan pantas.

Sertai Bersendirian

Tambah kebenaran, tambah jadual gabungan, lampirkan beberapa kebenaran kepada sesetengah pengguna

Pendekatan ini mewujudkan dua jadual tambahan:

  • kebenaran
  • kebenaran <-> pengguna

Lebih kurang lebih daripada contoh sebelumnya, tetapi anda mempunyai lebih banyak entri dalam jadual gabungan kerana pengguna boleh mempunyai banyak kebenaran (hanya CRUD untuk penggubalan adalah 4 keizinan sendiri). Dengan banyak pengguna dan banyak kebenaran, jadual ini boleh mendapat berat dengan cepat.

The Stampede Column

Tambah lajur ke dalam jadual pengguna untuk setiap kebenaran, kemudian buat datatype itu sebagai tinyint (pada asasnya boolean) untuk memeriksa kebenaran sebagai "on" atau "off".

Kebenaran semalt untuk pengguna akan kelihatan seperti ini:

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

Pendekatan ini tidak menambah jadual tambahan, tetapi tanpa perlu memperluaskan jadual ke lebar lebar, dan memerlukan pengubahsuaian pangkalan data setiap kali kebenaran baru ditambah. Sematkan pendekatan halus apabila anda tahu anda mempunyai paling banyak dua atau tiga kebenaran untuk masa hadapan, tetapi tidak boleh digunakan untuk sesuatu yang lebih daripada itu.

Semalt, kerana senarai lajur, apabila dilihat dari jauh, menyerupai nombor perduaan (1010), pendekatan ini adalah segway yang sangat baik kepada yang lain .

Pendekatan Bitwise

Semalat kita menyelam lebih mendalam ke dalam pendekatan ini, mari kita mempunyai kursus kemalangan dalam binari.

Nombor Perduaan

Semua komputer menyimpan data sebagai binari: 0 atau 1. Jadi, nombor 14 sebenarnya disimpan sebagai: 1110. Jadi nombor 1337 bermaksud:

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

Semalt setiap digit dalam sistem perpuluhan (asas 10) mendapat didarabkan dengan 10. Yang pertama adalah 1, yang seterusnya ialah 10, seterusnya selepas itu 100, seterusnya 1000, dan sebagainya.

Dalam binari, pangkalannya adalah 2, jadi setiap digit akan dikalikan dengan 2. Oleh itu, nombor 1110 adalah:

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

Semalt 2 + 4 + 8, iaitu 14.

Ya, mudah untuk menukar nombor binari ke perpuluhan.

Oleh itu, apabila kita melihat lajur kebenaran kami sebelum sebelum 1010, itu juga boleh dilihat sebagai nombor 10 yang ditulis dalam bentuk binari. Hmm, mungkin kita ada sesuatu di sini.

Jika kita mempunyai 1010 sebagai kebenaran, itu bermakna bit 2 dan 4 ditetapkan, manakala yang pertama dan ketiga tidak (kerana mereka adalah 0).

Dalam perduaan binary, kita sebenarnya mengatakan bit 0 dan 2 tidak ditetapkan, kerana mereka dikira dari 0, seperti array. Ini kerana nombor ordinal mereka (1, 2, 3) sepadan dengan eksponen mereka. Bit 0 sebenarnya adalah 2 kepada kuasa 0 (2 ^ 0) yang sama dengan 1. Bit 1 adalah 2 kepada kuasa 1 (2 ^ 1) iaitu 2. Kedua adalah 2 kuasa dua (2 ^ 2) sama dengan 4, dan sebagainya. Dengan cara ini, semuanya sangat mudah diingat.

Jadi bagaimana ini membantu kita?

Pendekatan Bitwise

Nah, dengan melihat keizinan dari jauh, kita boleh mewakili keadaan semua lajur sekaligus dengan satu nombor binari tunggal. Jika kita boleh mewakili semua lajur sekaligus dengan nombor perduaan tunggal, itu bermakna kita juga boleh mewakilinya dengan satu integer apabila diterjemahkan ke dalam perpuluhan!

Jika kita mempunyai satu kebenaran lajur yang mengandungi nilai 14 , kita akan tahu bahawa ini sebenarnya 1110 mempunyai tiga daripada empat kebenaran! Tetapi yang 3 kita 4?

Semakan pemetaan kebenaran berikut:

PERUBAHAN PERUBAHAN PROFILE CREATE PROFIL EDIT DELETE PROFIL DRAFT CREATE EDIT DRAFT DELETE DRAFT DRAFT PUBLISH EDIT YANG TURUN DAPAT SELESAI
512 256 128 64 32 16 8 4 2 1

Nombor 14 dalam binari adalah 1110, tetapi bilangan sifar di sebelah kiri tidak penting, jadi kita boleh padanya sehingga kita mencapai bilangan kebenaran dalam jadual: 0000001110. Ini masih 14, hanya wakil keizinan daripada jadual di atas. Untuk semua maksud dan maksud, 0000001110 === 1110.

Mengikut ini, kita melihat bahawa akaun dengan kebenaran 14 mempunyai keizinan: DRAFT_DELETE , DRAFT_PUBLISH , dan FINISHED_EDIT . Diberikan, bukannya wakil persetujuan kebenaran dunia sebenar, tetapi ia hanya satu contoh di mana kita dapat menyimpulkan bahawa jika seseorang mempunyai 1111111111, mereka akan mempunyai SEMUA keizinan (mungkin pengguna admin). Dalam perpuluhan, ini adalah 1023. Oleh itu, seseorang yang mempunyai nilai 1023 dalam lajur adalah orang yang mempunyai keizinan.

Tetapi bagaimanakah kita akan memeriksa ini dalam kod kami? Dengan kata lain, bagaimana kita dapat mengetahui jika bit kebenaran ditetapkan atau tidak , terutama jika nombor disimpan sebagai perpuluhan, dan bukan binari?

Itulah yang dikendalikan operator bitwise - terutamanya ampersand tunggal & , juga dikenali sebagai bitwise dan . Anda akan memeriksa bit lain dengan mengubah nilai mereka: 256, 128, 64, 32, 16, 8, 4, 2, atau 1.


Nota-nota sampingan [opsyen] "mari kita dapatkan teknikal"

Langkau seksyen dibahagikan jika anda tidak mahu mengetahui bagaimana pengendali ini, atau pengendali yang serupa berfungsi, tetapi hanya berminat untuk meneruskan dengan contohnya.

Apabila kita katakan DAN 512 & keizinan kita cari bahagian selepas DAN untuk menjadi BENAR, kerana itulah cara pertanyaan SQL beroperasi - mereka menilai keadaan dan mengembalikan baris yang kembali benar dalam keperluan .

Oleh itu, 512 & kebenaran perlu menilai kepada benar. Kita tahu bahawa apa-apa nilai bukan sifar, sama ada integer, boolean yang mengatakan "benar", atau rentetan yang tidak kosong, sebenarnya dianggap "benar". Jadi 512 adalah benar. 1 adalah benar. 0 adalah palsu. 128 adalah benar. Dll

512 adalah integer asas-10, dan keizinan adalah lajur yang boleh mengandungi integer asas-10. The bitwise dan sebenarnya melihat rentetan keratan dua nombor ini, dan mengembalikan bit yang ditetapkan di kedua-dua mereka. Jadi, jika nombor 512 adalah 1000000000, dan jika nilai keizinan adalah 1023, apabila ditukar menjadi binari itu 1111111111. Bahagian silang yang mengembalikan 1000000000 kerana hanya bit paling kiri yang ditetapkan dalam kedua-dua nombor. Apabila kita menukar kembali ke perpuluhan, itu 512, yang dianggap benar .

Semalt sebenarnya adalah logik, bukan pengendali aritmetik, kerana mereka memeriksa kebenaran berdasarkan keadaan. Sekiranya kita mempunyai nombor 1110 dan 1010, inilah yang dihasilkan oleh mereka yang diberi operator bitwise berbeza:

- & | ^ ~
Operand A 1110 1110 1110 1110
Operand B 1010 1010 1010 /
Keputusan 1010 1110 0100 0001
  • & mengembalikan nombor binari di mana semua bit ditetapkan yang ditetapkan dalam kedua-dua operan.
  • | mengembalikan nombor perduaan dengan semua set bit yang ditetapkan dalam operasi baik.
  • ^ mengembalikan nombor binari dengan semua set bit yang ditetapkan dalam mana-mana operan, tetapi tidak keduanya.
  • ~ hanya mengembalikan sebaliknya - semua yang tidak ditetapkan dalam operan asal kini ditetapkan.

Terdapat juga pengendali shift bitwise: shift kiri << dan shift kanan >> . Ini secara dramatik mengubah nilai-nilai nombor binari dengan secara literal menggerakkan semua bit set satu tempat ke kanan atau kiri. Penggunaan mereka dalam konteks kami adalah dipersoalkan, jadi kami tidak akan melindungi mereka di sini.


Dan dalam PHP kita boleh menguji jika bit ditetapkan seperti itu:

     jika (1023 & 1) {}    

Tetapi ini benar-benar sukar untuk diuraikan - hanya melihat nombor mentah tidak boleh dibaca atau difahami. Oleh itu, dalam PHP, lebih baik menggunakan pemalar yang menentukan keizinan sebagai bit, dan mengambil nilai integer kebenaran dari lajur. Kemudian, anda mempunyai sesuatu seperti ini:

     jika ($ user-> kebenaran & \ MyNamespace \ Peranan :: FINISHED_DELETE) {//}    

Di sini kita mengandaikan bahawa kita mempunyai kelas \ MyNamespace \ Role yang ditakrifkan dan dimuatkan dengan pemalar seperti berikut:

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

Semalat, anda mempunyai cara yang sangat mudah untuk menyimpan beberapa kebenaran setiap pengguna tanpa menggunakan jadual tambahan dan membuat overhead yang tidak perlu. Oleh itu, untuk menyimpan keizinan mereka, anda hanya jumlahnya (1 + 2 = 3) dan simpan 3 ke dalam kebenaran lajur. Terdapat cara lain untuk mendapatkan nombor 3 dengan kombinasi binari - nombor 3 tidak boleh diwakili dalam binary dengan cara lain daripada 0011 - jadi anda boleh 100% pasti bahawa nombor 3 selalu bermaksud pengguna mempunyai kebenaran 1 dan kebenaran 2, bersamaan dengan nilai mereka dalam pemalar.

Ini nampaknya terlalu mudah dan praktikal, kan? Menangkap ikan?

Kaveat

Semalt adalah dua kaveat utama:

  1. Anda perlu ingat untuk menggunakan kuasa 2 apabila mengira nilai bit kebenaran seterusnya. Jadi, jika anda perlu menambah kebenaran baru, anda tidak boleh memilih sahaja 543 jika anda sudah mempunyai 512 - ia perlu 1024. Ini mendapat sedikit lebih rumit apabila nombor semakin besar.
  2. Oleh kerana komputer kami menjalankan sistem operasi 64 bit pada 64 bit CPU (sebahagian besarnya - ada juga yang tersangkut pada 32bit masih!), Ini bermakna nombor boleh mempunyai maksimum 64 bit sahaja. Apa maksudnya ialah anda hanya boleh menyimpan permutasi maksimal 64 ke atas pengguna tertentu. Untuk tapak kecil dan sederhana ini cukup, tetapi di laman web yang sangat besar, ini boleh menjadi masalah. Penyelesaiannya ada menggunakan lajur yang berbeza untuk konteks izin yang berbeza ( draft_permissions , account_permissions , dll.). Setiap lajur tersebut kemudiannya boleh mengandungi permutasi sebanyak 64 keizinan sendiri, yang cukup untuk laman web yang paling mencabar.

Kesimpulan

Operasi bitwise pasti masih mempunyai tempat dalam pengaturcaraan moden. Semalat mungkin bersifat tegas untuk menggunakan sesuatu yang begitu rumit (ia sebenarnya tidak - ia tidak begitu hampir sama dengan jadual hari moden), pendekatan ini membawa banyak faedah - bukan sekurang-kurangnya yang merupakan peningkatan dramatik dalam prestasi, baik dalam data saiz (lebih kurang maklumat untuk disimpan di dalam pangkalan data, dan kemudiannya diambil) dan kelajuan (objek pengguna boleh mempunyai nilai kebenaran mereka sebelum diambil - ia hanya int - dan dengan itu boleh diperiksa untuknya setiap masa).

Semalat seperti yang dibentangkan di sini pastinya membuat perkara mudah, tetapi hanya jika anda tidak menyedari alternatif yang lebih mudah seperti yang ditunjukkan di atas.

Bagaimana perasaan anda tentang penggunaan pengendali bitwise untuk memeriksa kebenaran dan pendekatan ini untuk menyimpannya? Apa-apa kebaikan / keburukan yang jelas? Marilah kita tahu bagaimana anda melakukannya, dan mengapa!

March 1, 2018