Introduction to Memcached - php

I am trying to use Memcached right now, and I am a little confuse about this:
First, do I need to make a class for Memcached? like this: click me! or is it automatically works? do I just need to make a connection to the memcached server and then I can cache data?
UPDATE
When I tried to use the code exiang provided, my output in all of the var_dumps are boolean false. Anybody knows why is this happened?
UPDATE PART 2
When I tried to use this code echo $m->getResultMessage(),"\n"; it returns:
SERVER HAS FAILED AND IS DISABLED UNTIL TIMED RETRY

make sure you have enabled the php memcache module, it looks like this in your phpinfo
Make sure your memcached server is running
Then, you can use it directly like this:
http://php.net/manual/en/memcached.set.php
<?php
$m = new Memcached();
$m->addServer('localhost', 11211);
$m->set('int', 99);
$m->set('string', 'a simple string');
$m->set('array', array(11, 12));
/* expire 'object' key in 5 minutes */
$m->set('object', new stdclass, time() + 300);
var_dump($m->get('int'));
var_dump($m->get('string'));
var_dump($m->get('array'));
var_dump($m->get('object'));
?>

Related

How does addServer method of PHP Memcache/Memcached work?

I'm currently running PHP Memcache on Apache server. Since Memcache and Memcached have similar inner workings this question is about both of them.
I was wondering through the addServer method of memcached here and the second comment on the user section is this:
Important to not call ->addServers() every run -- only call it if no servers exist (check getServerList() ); otherwise, since addServers() does not check for dups, it will let you add the same server again and again and again, resultings in hundreds if not thousands of connections to the MC daemon. Specially when using FastCGI.
It is not clear what is meant by "every run". Does it mean calling addServer within the script multiple times or within multiple requests by different users/remote clients? Because consider the following script:
<?php
$memcache_obj = new \Memcache;
//$memcache_obj->connect('localhost', 11211); --> each time new connection, not recommended
$memcache_obj->addServer('localhost', 11211,true,1,1,15,true,function($hostname,$port){
//echo("There was a problem with {$hostname} at {$port}");
die;
});
print_r($memcache_obj->getExtendedStats());
?>
If as client, I make an xmlhttp request to above script, I will get something like this:
Array
(
[localhost:11211] => Array
(
[pid] => 12308
[uptime] => 3054538123
....
So far so good, if I uncomment the addServer part and execute like this:
<?php
$memcache_obj = new \Memcache;
print_r($memcache_obj->getExtendedStats());
?>
Then I get this:
<br />
<b>Warning</b>: MemcachePool::getserverstatus(): No servers added to
memcache connection in <b>path/to/php</b> on line <b>someLineNumber</b><br />
So obviously at least a server has to be added when the php script is called by the remote client. Then which of the following is true here:
we should be careful not to call `addServer`` within the same PHP script too many times. (I am inclined to understand it this way)
we should be careful not to call addServer among multiple requests (For example 2 user's calling same php script etc. I can't seem to figure out how this can ever be done.)
You do have to add the server once, else you will get this error. As the comment suggests you should use getServerList() to check if the servers have been added already and add them if they are not present:
<?php
$memcache_obj = new \Memcache;
//$memcache_obj->connect('localhost', 11211); --> each time new connection, not recommended
if (!memcache_obj->getServerList()){
$memcache_obj->addServer('localhost', 11211,true,1,1,15,true,function($hostname,$port){
//echo("There was a problem with {$hostname} at {$port}");
die;
});
}
print_r($memcache_obj->getExtendedStats());
?>

PHPRedis and SMEMBERS

I'm trying some stuff with Redis and PHP, and I've encountered a problem when it came to work with SETS and SMEMBERS.
I'm using Symfony2 and SncRedisBundle.
$redis->multi();
// Some stuff
$result = $redis->smembers("myset");
var_dump($result);
die();
$redis->exec();
Here's the dump
object(Redis)[990]
public 'socket' => resource(841, Redis Socket Buffer)
I'm a bit stuck now, I don't know how I can work with the result since there's nothing really visible or explained on php-redis documentation.
Can someone help me?
You should check the result of $redis->exec() instead of the result of smembers. The principle of MULTI/EXEC blocks is that command executions are delayed until the EXEC command. At this point, all commands are executed atomically and their results are sent back to the client.
See this example: https://github.com/nicolasff/phpredis#transactions
Note that using a MULTI/EXEC block with just one command inside is pointless and does not bring any benefits.

Why does Memcached add() always succeed, regardless of expire time?

I'm adding a key using Memcached like so:
$valueToStore = time(); // some number
$success = $memcached->add( 'test_key', $valueToStore, 20 ); // cache for 20 seconds
But it's always succeeding when I call it in a different session, even before 20 seconds have passed. According to the docs at http://php.net/manual/en/memcached.add.php, it should be returning FALSE until the key expires (because the key already exists).
I'm running on a single development server with plenty of free cache space. Any idea what might be happening?
php -v returns: PHP 5.5.9-1ubuntu4.3
memcached version 2.1.0
libmemcached version 1.0.8.
You need to be distinct if you are using the Memcache class or the Memcached class. Your cache design is a bit strange. You should be checking the cache to first see if the item is there. If the item is not then store it. Also Memcache has some strange behavior on using the boolen type as the third argument. You should MEMCACHE_COMPRESSED. I think you are using Memcache.
To illustrate how to fix your problem:
$in_cache = $memcached->get('test_key');
if($in_cache)
return $in_cache;
else
$valueToStore = time();
$memcached->add('test_key', $valueToStore, MEMCACHE_COMPRESS, 20);

Memcached passing data using php

I have installed memcached 1.4.4-14 on my windows systems. I have started the service and everything is in order. Now all I am trying to do is test it using .php which is served using IIS.
So I right a basic index.php page and browse through IIS. I can render the page and general .php works. Its just nothing happens with the memcache. There is so much confusion out there about what pre-requisites I need to install. I can't fathom which ones are essential. The PHP I installed is a new clean install with only the php_memcache.dll extensions dumped in .php.
It is worth noting that in phpinfo I can see no reference to memcache.
Would love some basic assistance.
Here is my example that I am using, I believe it is the standard test for memcache session dump.
session_start();
header("Content-type: text/plain");
$memcache = new Memcache;
$memcache->connect("localhost",11211); # You might need to set "localhost" to "127.0.0.1"5
echo $memcache->get(session_id());
Thank you.
If you're interested in using compression, please note that, at least for PHP version 5.3.2 and Memcache version 3.0.4, when retrieving a key who's value is a numeric or boolean type, PHP throws a notice of the following:
Message: MemcachePool::get(): Failed to uncompress data
The way around this is to test your variable type before setting or adding it to Memcache, or even cast it as a string.
<?php
$key = 'mc_key';
$value = 12345;
$compress = is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED;
$mc= new Memcache;
$mc->connect('localhost', 11211);
$mc->set($key, $value, $compress);
echo $mc->get($key);
//Alternative is to cast the variable
$value = is_scalar($value) ? (string)$value : $value;
$mc->set($key, $value, MEMCACHE_COMPRESSED);
?>

PHP Memcached Session Locking Enable

I use "memcached" to store php sessions.
It is important, that request must be synchronously (to avoid duplicate transactions or operations), but while using "memcached" session, "session locking" not works.
is some method to lock "memcached" session until one request will executed?
There's nothing built in no, but you can write stuff yourself to make your code atomic.
$key = 'lockable_key_name';
$lockkey = $key.'##LOCK';
if($memcached->add($lockkey, '', 60)) {
$storedvalue = $memcached->get($key);
// do something with $storedvalue
$memcached->set($key, $newvalue);
// release
$memcached->delete($lockkey);
}
In your code you could check for the lock by doing:
if(!$memcached->get($lockkey)) {
// then do something
}
If the get method returns false then there's no lock, or the operation has hung and passed the 60 second timeout specified in the add call above.
Since you were asking for credible/official sources:
The memcached extension supports session locking since version 3.0.4, according to the changelog document on the PECL extension page: http://pecl.php.net/package-info.php?package=memcache&version=3.0.4
If you happen to run an earlier version (it means that your version of the memcached extension is more than 4 years old), you are out of luck and should upgrade.
Maybe try something like $(field_name)_is_locked = true when you start then when you are done $(field_name)_is_locked = false and pass the variable to the server when you update it.

Categories