位運(yùn)算在PHP實(shí)際項(xiàng)目當(dāng)中的運(yùn)用是怎樣的

這篇文章給大家介紹位運(yùn)算在PHP 實(shí)際項(xiàng)目當(dāng)中的運(yùn)用是怎樣的,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

成都創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站與策劃設(shè)計(jì),萊陽(yáng)網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:萊陽(yáng)等地區(qū)。萊陽(yáng)做網(wǎng)站價(jià)格咨詢:18982081108

來(lái)回顧一下這些基礎(chǔ)知識(shí),同時(shí)也會(huì)講位運(yùn)算在 PHP 實(shí)際項(xiàng)目當(dāng)中的高級(jí)技巧。

一、位運(yùn)算知識(shí)回顧

PHP 手冊(cè)當(dāng)中,專門(mén)對(duì)位運(yùn)算及位運(yùn)算符進(jìn)行了使用介紹。

https://www.php.net/manual/zh/language.operators.bitwise.php

1) 按位與運(yùn)算符:&

之所以稱為位運(yùn)算,指的是在運(yùn)算過(guò)程中,我們會(huì)把兩組需要位運(yùn)算的數(shù)值進(jìn)行二進(jìn)制化,然后兩組二進(jìn)制的數(shù)字從低位向左對(duì)齊。這里的位指的是二進(jìn)制數(shù)字的位置。而按位與運(yùn)算符指的是兩組數(shù)值每一位相與,同為 1 則 結(jié)果為 1,否則為 0。

看 PHP 示例:

echo 1 & 3; // 輸出:1

為什么會(huì)輸出 1 呢?

那是因?yàn)椋?/p>

1 的二進(jìn)制表示結(jié)果為:01。

3 的二進(jìn)制表示結(jié)果為:11。

那么這兩組二進(jìn)制結(jié)果對(duì)齊之后的運(yùn)算流程如下:

0111——01

從右往左進(jìn)行位運(yùn)算,都 為 1 則結(jié)果為1,否則為 0。結(jié)果自然是 01。而 01 轉(zhuǎn)換成十進(jìn)制就是 1 。所以,輸出的結(jié)果為 1。

再看一組示例吧:

echo 2 & 10; // 輸出:2

我們來(lái)看看運(yùn)算過(guò)程:

101010——————0010

0010 轉(zhuǎn)換成十進(jìn)制就是 2。

一定要記得是向左對(duì)齊?;蛘叻Q為低位順位對(duì)齊模式。

如果你不會(huì)十進(jìn)制轉(zhuǎn)二進(jìn)制或二進(jìn)制轉(zhuǎn)十進(jìn)制不會(huì)。那么,下面這兩個(gè)方法能幫助你。

echo decbin(10); // 十進(jìn)制轉(zhuǎn)二進(jìn)制。echo bindec(10); // 二進(jìn)制轉(zhuǎn)十進(jìn)制。

2) 按位或運(yùn)算符:|

這個(gè)跟上面的按位與運(yùn)算符稍微有一點(diǎn)不同:只要兩組數(shù)字當(dāng)中有只要有一位是 1 則結(jié)果就為 1。

看示例:

echo 2 | 10; // 輸出結(jié)果:10

運(yùn)算過(guò)程:

101010——————1010

1010 的十進(jìn)制結(jié)果就是 10。

3) 按位異或運(yùn)算符:^

這個(gè)運(yùn)算符比較有意思:兩組數(shù)字必須是一組 0 與 1 結(jié)果才為 1。1 與 1 和 0 與1 都是 0。

看示例:

echo 1 ^ 1; // 輸出結(jié)果:0echo 1 ^ 0; // 輸出結(jié)果:1

1 ^ 1 運(yùn)算過(guò)程:

01
01
——
00

1 ^ 0 運(yùn)算過(guò)程:

0100——01

這個(gè)很簡(jiǎn)單。沒(méi)啥好說(shuō)的。反正不相同就為 1,相同就為 0。

4) 其他位運(yùn)算符:~、>>、<<

~ 按位取反運(yùn)算符、>> 右移運(yùn)算符、<< 左移運(yùn)算符。它們的操作數(shù)都是一個(gè)。所以,與上面的兩個(gè)操作數(shù)的位運(yùn)算符有著非常明顯的區(qū)別。在 PHP 實(shí)際編程當(dāng)中,運(yùn)用比較少。權(quán)當(dāng)知識(shí)了解即可。

二、高級(jí)動(dòng)用技巧

我們?cè)谏厦鎸?duì)位運(yùn)算符的知識(shí)進(jìn)行了回顧。為的就是要在接下來(lái)的實(shí)際項(xiàng)目中怎樣運(yùn)用它解決實(shí)際問(wèn)題。

我們首先來(lái)看一個(gè)系統(tǒng)中常見(jiàn)的需求:

有一個(gè)廣告表,我們要對(duì)廣告做顯示控制:

  • 手動(dòng)上下線。

  • 只允許 VIP 查看。

可能的表結(jié)構(gòu)如下:

CREATE TABLE `finger_ad` (
  `ad_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `ad_name` varchar(50) NOT NULL COMMENT '廣告名稱',
  `ad_image_url` varchar(255) NOT NULL COMMENT '廣告圖片',
  `ad_url` varchar(255) NOT NULL COMMENT '廣告圖片URL跳轉(zhuǎn)地址',
  `is_vip` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否僅限 VIP 顯示',
  `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT '顯示狀態(tài):1顯示、0隱藏',
  PRIMARY KEY (`ad_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='廣告表';

假如后期,我們需求更改了。需要再增加幾種限制:

  • 已登錄用戶

  • 未登錄用戶

  • 30 天內(nèi)未登錄用戶

  • 注冊(cè) 30 天的用戶

遇到這種限制條件的需求,開(kāi)發(fā)同學(xué)是不是很傷腦筋?

可能很多開(kāi)發(fā)第一反應(yīng)就是在表結(jié)構(gòu)增加這種新增的限制條件字段。一切看來(lái)似乎很美好。

的確,這樣添加字段是最快最容易的方式。也能完成我們的需求。

但是,這樣會(huì)引來(lái)如下毛?。?/p>

  • 每次增加限制條件。我們都要增加字段。這種對(duì)數(shù)據(jù)庫(kù)的更動(dòng)能少改就少改。畢竟,無(wú)限制的增加字段不可取。

  • 假如廣告表數(shù)據(jù)量很大。大到增加一個(gè)字段需要幾分鐘的時(shí)候,這會(huì)給數(shù)據(jù)庫(kù)服務(wù)器造成讀寫(xiě)壓力。

  • 條件越多,SQL 條件語(yǔ)句就會(huì)越來(lái)越長(zhǎng)。

那么,還有沒(méi)有更好的方式解決這些問(wèn)題呢?

答案:有!

這就是我們今天要講的按位與運(yùn)算符的高級(jí)技巧。

我們把上面的表結(jié)構(gòu)改一下:

DROP TABLE IF EXISTS `finger_ad`;CREATE TABLE `finger_ad` (
  `ad_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `ad_name` varchar(50) NOT NULL COMMENT '廣告名稱',
  `ad_image_url` varchar(255) NOT NULL COMMENT '廣告圖片',
  `ad_url` varchar(255) NOT NULL COMMENT '廣告圖片URL跳轉(zhuǎn)地址',
  `bit_condition` INT(11) UNSIGNED NOT NULL COMMENT '位運(yùn)算條件:1-登錄可訪問(wèn)、2-未登錄可訪問(wèn)、4-30天注冊(cè)可訪問(wèn)、8-30天未登錄可訪問(wèn)、16-未消費(fèi)可訪問(wèn)、32-VIP可訪問(wèn)',
  `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT '顯示狀態(tài):1顯示、0隱藏',
  PRIMARY KEY (`ad_id`)) ENGINE=InnoDB DEFAULT CHARSET UTF8 COMMENT='廣告表';

我們把所有的條件都去掉了。增加了一個(gè)字段: bit_condition 。把所有的條件都組合到一個(gè)字段。

那我們此時(shí)該如何寫(xiě)代碼呢?

比如,現(xiàn)在要添加如下限制條件的廣告:

只允許登錄用戶訪問(wèn)或已注冊(cè) 30 天用戶或是 VIP 用戶才允許訪問(wèn)該廣告。

那么,這個(gè)廣告的 bit_condition 該如何設(shè)置值呢?很簡(jiǎn)單,把這幾個(gè)條件的位值直接相加。此時(shí)值為:37。

很多可能會(huì)很奇怪。設(shè)置為 37 ,我怎么知道是這幾個(gè)值的和呢?如果對(duì) Linux 系統(tǒng)權(quán)限熟悉的同學(xué)就很容易理解這種做法。實(shí)際上,這里運(yùn)用了按位與運(yùn)算的特性:任意組合相加的值不會(huì)重復(fù)。

這個(gè)理解起來(lái)有一定難度。我三兩句也很難給你梳理明白。大家可以在網(wǎng)上深入挖掘一下這方面兒的知識(shí)。你只需要知道這一點(diǎn)特點(diǎn)即可。

那么,現(xiàn)在我們?cè)撊绾螌?xiě) SQL 呢?

示例如下:

SELECT * FROM finger_ad WHERE display = 1 AND bit_condition & 3 = bit_condition

這條 SQL 語(yǔ)句當(dāng)中的 3 對(duì)應(yīng)的是當(dāng)前用戶針對(duì)這么多條件得到的數(shù)值。如果 bit_condition位值是與 3 按位與與 bit_condition 結(jié)果相同,說(shuō)明條件符合。

我們通過(guò)一個(gè)字段解決了所有條件的問(wèn)題。著實(shí)得感謝按位與運(yùn)算符的特性。同時(shí)也對(duì) MySQL能支持位運(yùn)算符感到開(kāi)心。

那么,它有什么缺點(diǎn)呢?

想必有經(jīng)驗(yàn)的同學(xué)已經(jīng)看出來(lái)了。這種寫(xiě)法只能滿足包含關(guān)系。假如要實(shí)現(xiàn)同時(shí)滿足 3 個(gè)條件才能訪問(wèn)就不行了。或者,一個(gè)滿足另外一個(gè)取反。

優(yōu)點(diǎn)明顯,同樣缺點(diǎn)也很明顯。大家要根據(jù)實(shí)際情況來(lái)選用。

關(guān)于位運(yùn)算在PHP 實(shí)際項(xiàng)目當(dāng)中的運(yùn)用是怎樣的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

分享題目:位運(yùn)算在PHP實(shí)際項(xiàng)目當(dāng)中的運(yùn)用是怎樣的
URL分享:http://muchs.cn/article22/phogjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、App設(shè)計(jì)、虛擬主機(jī)、企業(yè)建站、網(wǎng)站導(dǎo)航、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司