Michael Franze
Michael Franze

Reputation: 435

Sharing Memcache with PHP and Python

I am trying to share a Memcache key between Python and PHP. Python writes the key and PHP reads it. I am using the Cakephp framework, with php-pecl-memcache (not php-pecl-memcached), and the python-memcache all python library.

Python:

  mc = memcache.Client( ["127.0.0.1:11211"])
  key = "key1"
  value = 1323779849
  mc.set(key, value)

PHP:

  echo Cache::read('key1', 'memcached');

PHP can't read the variable, I get weird "MemcachePool::get() [http://php.net/memcachepool.get]: Failed to uncompress data" errors; I suspect it has to do with memcached flags that are set differently in each library.

This is what happens when I telnet to memcached:

Python sets key:

 get key1
 VALUE key1 1 12
 1323779849
 .
 END

PHP sets key:

 get key1
 VALUE key 1 0 12
 1323779849
 END

Upvotes: 2

Views: 2710

Answers (3)

Gishas
Gishas

Reputation: 554

I had a similar problem, using PHP and pymemcache. I serialized Python dictionary with https://www.php2python.com/wiki/function.serialize/ and wrote that to memcache. PHP side also had it's own way of storing into memcache, and memcache values written by PHP and Python seemed to be the same, but PHP couldn't read Python set value properly, so it puzzled me a lot. PHP read it as a String, being unable to deserialize it / convert it to an Array. Then I got to read memcache values using netcat, like this:

echo -e 'get my-key\r' | nc 192.168.1.17 11211

Python set value returned:

VALUE my-key 0 1460

, while PHP set value had:

VALUE my-key 1 1460

Not knowing how to deal with these flags, I simply used this - on PHP side, if I got a String "a:{s:6..." instead of an Array, I used PHP's unserialize() method to make it an Array and it worked.

Upvotes: 0

Michael Franze
Michael Franze

Reputation: 435

Finally got it to work. Lot's of stuff wasn't working as expected.

  1. One problem is that php and python use different flags to do different things. Not a problem in an all-python or all-php solution, but for inter-environment communication a real problem. A useful resource is http://www.hjp.at/zettel/m/memcached_flags.rxml, which shows that python-memcache flags long integer as '2', which php-memcache does not understand, hence the compression error. I amended python-memcache to include a 'flag-override' in the set function. This variable simply forces a particular flag irrespective of what python memcache thinks it ought to be. This allowed me to re-flag Int from 2 to 0. I will prob branch the current version of python-memcache and submit it to Github. This allowed me to force the python long int flag (2) to something php would understand (0).

  2. CakePhp prior to 1.3.3 stores all keys in memcached with an additional key_expires key, flagged as 768, etc, etc. Without this additional key it cannot find the key you are looking for. Thankfully this behaviour was dumped in later Cakephp version (I simply upgraded to 1.3.13) and it works well now.

Upvotes: 3

Drachenfels
Drachenfels

Reputation: 3286

When you put something via python memcached, it's probably pickled. So PHP cannot unpickle it. I would try to use some kind of very basic type maybe ctypes? Maybe raw strings?

Upvotes: 0

Related Questions