Home  >  Article  >  类库下载  >  Exploring the reasons why PHP’s memcache extension and memcached extension read and write arrays are incompatible

Exploring the reasons why PHP’s memcache extension and memcached extension read and write arrays are incompatible

高洛峰
高洛峰Original
2016-10-15 16:19:561298browse

Background

Many teams in the company have recently upgraded php7. Currently, the only extension that supports php7 reading mc is memcached. However, many projects in the company will share a mc cluster to store and retrieve user session data. When saving, the memcache extension is used to write it in the form of array when logging in. When reading, naturally, the memcache extension is used to read it out in the form of array. But now it can only be read using memcached. But as far as I know, the two are incompatible with each other when reading data in array form, so I want to find out why.

Verification

Verify whether the memcache extension and memcached extension read and write array data are incompatible Test script:

addServer('10.199.189.129', 11511); 
$key = 'testString'; 
$mc->set($key, 'test success'); 
var_dump($mc->get($key)); 
$mc2 = new memcached; 
$mc2->addServer('10.199.189.129', 11511); 
var_dump($mc2->get($key)); 
echo "========== test array ============\n"; 
$key2 = 'testArray'; 
$mc->set($key2, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key2));

Execution result:

➜ ~ 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)

Judging from the results, it confirms our previous statement.

Guess the reason

Since there is no problem with the string, the problem is in the array format. So I suspect that the serialization method when the array is stored in mc is different. So we conducted further testing: Write a test script

addServer('10.199.189.129', 11511); 
$mc2 = new memcached; 
$mc2->addServer('10.199.189.129', 11511); 
$key2 = 'testArray1'; 
$key3 = 'testArray2'; 
$mc->set($key2, [1,2,3]); 
$mc2->set($key3, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key3));

Execution results:

➜ ~ 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) }

Next, directly connect to mc to view

➜ ~ telnet 10.199.189.129 11511 
Trying 10.199.189.129... 
Connected to 10.199.189.129
Escape character is '^]'. 
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

From the results, we can find that the results of memcache and memcached written to mc are the same , which means our guess is wrong. The serialization processing of the two values ​​is exactly the same, the difference lies in the different flags of the values. When memcache stores array data, falg is 1, while memcached is 4. We know that the flag of the value of mc is provided for users to customize, which facilitates different processing when reading. But why are the flag definitions of the two different? With this question in mind, try to find the reason by reading the source code of the two extensions.

Read the source code of two extensions

memcache

php_memcache.h:

#define MMC_SERIALIZED 1 
#define MMC_COMPRESSED 2

memcached

php_memcached.c

#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

After reading the source code, I found that memcache defines the flag of the array format as 1, while memcached defines the array format flag as 1. The values ​​stored in mc by php are distinguished in detail, and the data types are defined as string, long, double, etc. In other words, when you use memcache, the execution result of running

addServer('10.199.189.129', 11511); 
$mc->set('123',1); 
var_dump($mc->get('123'));

is:

string(1) "1"

You obviously saved a key with the value 1, but when you read it, it was a string. And when you use memcached, the execution result of running

addServer('10.199.189.129', 11511); 
$mc->set('123',1); 
var_dump($mc->get('123'));

is:

int(1)

Conclusion

The reason why memcache extension and memcached extension are not compatible with reading and writing array data is that memcached defines identifiers of various data types in order to distinguish data types in detail, and the array identifier is inconsistent with the array identifier defined by memcache.
In order to ensure that the data written directly by memcache extension and memcached extension can read each other, mc can only be written in string format.
After this exploration, I also realized that there are many ways that memcached is better than memcache. I believe that with the popularity of php7, memcache will be eliminated by history at an accelerated pace.


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Related articles

See more