搜尋
首頁类库下载PHP类库php的memcache擴充和memcached擴充讀寫陣列不相容原因探究

背景

最近公司許多團隊進行升級php7,目前支援php7讀取mc的擴充只有memcached。但是公司許多專案都會共用一個mc集群來訪問用戶session數據,存的時候是登陸時用memcache擴展以array的形式寫進去,讀的時候自然是用memcache擴展以array的形式讀出來。 但現在只能使用memcached進行讀取。但據我所知兩者讀取array形式的資料是互不相容的,因此想探究一下究竟是為什麼。

驗證

驗證memcache擴展和memcached擴展讀寫數組資料是否不相容測試腳本:

<?php 
echo "========== test string ============\n"; 
$mc = new memcache; 
$mc->addServer(&#39;10.199.189.129&#39;, 11511); 
$key = &#39;testString&#39;; 
$mc->set($key, &#39;test success&#39;); 
var_dump($mc->get($key)); 
$mc2 = new memcached; 
$mc2->addServer(&#39;10.199.189.129&#39;, 11511); 
var_dump($mc2->get($key)); 
echo "========== test array ============\n"; 
$key2 = &#39;testArray&#39;; 
$mc->set($key2, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key2));

執行結果:

➜ ~ php /apps/dat/test.php 
========== test string ============ 
string(12) "test success" 
string(12) "test success" 
========== test array ============ 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 
int(0)

從結果來看,印證了我們之前的說法。

猜測原因

由於string沒有問題,出問題是在array格式裡面。所以懷疑是array存進mc時的序列化方法不同。於是乎進行進一步的測試:編寫測試腳本

<?php 
echo "========== test array ============\n"; 
$mc = new memcache; 
$mc->addServer(&#39;10.199.189.129&#39;, 11511); 
$mc2 = new memcached; 
$mc2->addServer(&#39;10.199.189.129&#39;, 11511); 
$key2 = &#39;testArray1&#39;; 
$key3 = &#39;testArray2&#39;; 
$mc->set($key2, [1,2,3]); 
$mc2->set($key3, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key3));

執行結果:

➜ ~ php /apps/dat/test.php 
========== test array ============ 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

接下來直接連接mc進行查看

➜ ~ telnet 10.199.189.129 11511 
Trying 10.199.189.129... 
Connected to 10.199.189.129
Escape character is &#39;^]&#39;. 
get testArray1 
VALUE testArray1 1 30 
a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} 
END 
get testArray2 
VALUE testArray2 4 30 
a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} 
END

從結果來看,我們可以發現,memcache和memcached寫到mc裡面的結果是一樣的,也就是說我們的猜測是錯的。兩個值的序列化處理一模一樣,差異在於值的flag不同。 memcache儲存array資料的時候,falg為1,而memcached為4. 我們知道,mc中值的flag是提供給用戶自訂,方便再讀取的時候做不同的處理。但為什麼兩者的flag定義會不相同呢。 抱著這個疑問,試著透過閱讀兩個擴充的原始碼來找出原因。

閱讀兩個擴充的原始碼

memcache

php_memcache.h:

#define MMC_SERIALIZED 1 
#define MMC_COMPRESSED 2

memcached

php_memcached.cache

reee

reee

碼,發現數字php存進mc中的值進行詳細的型別區分,將資料型別定義了string,long,double等等的資料型別。也就是說,當你使用memcache的時候,運行

#define MEMC_VAL_IS_STRING 0 
#define MEMC_VAL_IS_LONG 1 
#define MEMC_VAL_IS_DOUBLE 2 
#define MEMC_VAL_IS_BOOL 3 
#define MEMC_VAL_IS_SERIALIZED 4 
#define MEMC_VAL_IS_IGBINARY 5 
#define MEMC_VAL_IS_JSON 6 
#define MEMC_VAL_IS_MSGPACK 7

執行結果是:

<?php
$mc = new memcache; 
$mc->addServer(&#39;10.199.189.129&#39;, 11511); 
$mc->set(&#39;123&#39;,1); 
var_dump($mc->get(&#39;123&#39;));

你明明存了一個值為數字1的key,但是讀取的時候卻為字符串。 而當你使用memcached的時候,運行

string(1) "1"

執行結果是:

<?php$mc = new memcached; 
$mc->addServer(&#39;10.199.189.129&#39;, 11511); 
$mc->set(&#39;123&#39;,1); 
var_dump($mc->get(&#39;123&#39;));

結論🎜

memcache擴展和memcached擴展讀寫數組資料不相容的原因是,memcached為了詳細地區分資料類型,定義了各種資料類型的標識,而其中數組的標識與memcache定義的數組標識不一致導致。
為了確保memcache擴充和memcached擴充直接寫的資料可以互相讀取,只能用string的格式寫入mc。
經過這次探究,也讓我認識到許多memcached比memcache更優秀的地方,相信隨著php7的普及,memcache會加速地被歷史所淘汰。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中