Memcache
在线手册:中文 英文
PHP手册

Memcache::add

(PECL memcache >= 0.2.0)

Memcache::add增加一个条目到缓存服务器

说明

bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )

Memcache::add()方法在缓存服务器之前不存在key时, 以key作为key存储一个变量var到缓存服务器。 同样可以使用函数memcache_add()

参数

key

将要分配给变量的key。

var

将要被存储的变量。字符串和整型被以原文存储,其他类型序列化后存储。

flag

使用MEMCACHE_COMPRESSED标记对数据进行压缩(使用zlib)。

expire

当前写入缓存的数据的失效时间。如果此值设置为0表明此数据永不过期。你可以设置一个UNIX时间戳或 以秒为单位的整数(从当前算起的时间差)来说明此数据的过期时间,但是在后一种设置方式中,不能超过 2592000秒(30天)。

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE. 如果这个key已经存在返回FALSEMemcache::add()方法的其他行为类似 Memcache::set()

范例

Example #1 Memcache::add()示例

<?php

$memcache_obj 
memcache_connect("localhost"11211);

/* 面向过程编程 API */
memcache_add($memcache_obj'var_key''test variable'false30);

/* 面向对象编程 API */
$memcache_obj->add('var_key''test variable'false30);

?>

参见


Memcache
在线手册:中文 英文
PHP手册
PHP手册 - N: 增加一个条目到缓存服务器

用户评论:

duerra at nospam dot yahoo dot com (18-Nov-2010 12:06)

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->add($key, $value, $compress);

echo
$mc->get($key);

//Alternative is to cast the variable
$value = is_scalar($value) ? (string)$value : $value;
$mc->add($key, $value, MEMCACHE_COMPRESSED);
?>

Davide Renzi (18-Feb-2010 09:16)

Race conditions happen on an heavy load server when more than one thread tries to execute memcache_add.
For example if thread A and thread B try to save the same key you can test that sometimes both return TRUE.
To have the right behaviour you can verify that the correct value is in the assigned key:

<?php
function memcache_safeadd(&$memcache_obj, $key, $value, $flag, $expire)
{
    if (
memcache_add($memcache_obj, $key, $value, $flag, $expire))
    {
        return (
$value == memcache_get($memcache_obj, $key));
    }
    return
FALSE;
}
?>

matt (04-Aug-2009 02:39)

It's also good to note that add will succeed if the key exists but is expired

ktamas77 at gmail dot com (27-Apr-2009 12:08)

skeleton of a thread safe updater for an incremental counter:

<?php

$key
= "counter";
$value = $memcache->increment($key, 1);
if (
$value === false) {
  
// --- read from DB ---
  
$query = "SELECT value FROM database";
  
$result = mysql_query($query);
  
$row = mysql_fetch_assoc($result);
  
$db_value = $row["value"];
  
$add_value = $memcache->add($key, $db_value + 1, 0, 0);
   if (
$add_value === false) {
     
$value = $memcache->increment($key, 1)
      if (
$value === false) {
         
error_log ("counter update failed.");
      }
   } else {
     
$value = $db_value + 1;
   }
}

// --- display counter value ---
echo $value;

?>

rune(at)intermedia(dot)no (06-Oct-2008 07:04)

Key may not exceed 250 chars according to memcached protocol.

php at tapirpirates dot net (03-Apr-2008 04:32)

memcache has no locking mechanism, but you could implement it manually.

basic locking through the add method:

<?php
// locks time out after 5 seconds
Define( 'LOCK_TIMEOUT', 5 );

$lock = $memcache->add( 'lock:' . $key, 1, false, LOCK_TIMEOUT );
if (
$lock ) {
 
// no lock on this key, so do what you want
 
$value = $memcache->get( $key );
 
$memcache->set( $key, $value+1 );
 
// release lock
 
$memcache->delete( 'lock:' . $key );
}
else {
 
// variable is currently locked, so do something else
}
?>

furthermore, you could implement a loop which checks if there is a lock, and if there is, wait some time and try again, until the lock is free.

remember: locking will heavily increase your memcache hits and obviously is not what memcache is made for. altough it's not possible for a lock to be forgotten (there's a timeout after all) there is the possibility to get locked out for a very long time.

an alternative may be to implement locking through apc_add (or shared memory), but i've never tried it.

if you absolutley have to implement locks, memcached is probably the wrong solution anyway.

roberto at spadim,com dot br (18-Jun-2007 06:13)

[c.2007]
if you read source code for MMC_SERIALIZED you will see at line ~1555 that [a line ~1560]
!(is_string,is_long,is_double,is_bool)

[is] serialized and that serialized values are flaged as MMC_SERIALIZED for return (fetch) code unserialize these values again