Memcached::cas

(PECL memcached >= 0.1.0)

Memcached::cas比较并交换一个项目

描述

public Memcached::cas(
    string|int|float $cas_token,
    string $key,
    mixed $value,
    int $expiration = 0
): bool

Memcached::cas() 执行“检查和设置”操作,以便仅当自上次由本客户端获取该项目以来没有其他客户端更新该项目时才会存储该项目。 检查通过 cas_token 参数完成,该参数是 memcache 为现有项目分配的唯一 64 位值。 有关如何获取此令牌,请参阅 Memcached::get*() 方法的文档。 请注意,由于 PHP 整数空间的限制,令牌被表示为浮点数。

参数

cas_token

与现有项目关联的唯一值。 由 memcache 生成。

key

要存储值的键。

value

要存储的值。

expiration

过期时间,默认为 0。 有关更多信息,请参见 过期时间

返回值

如果成功,则返回 true,如果失败,则返回 falseMemcached::getResultCode() 将返回 Memcached::RES_DATA_EXISTS,如果要存储的项目自上次获取后已修改。

示例

示例 #1 Memcached::cas() 示例

<?php
$m
= new Memcached();
$m->addServer('localhost', 11211);

do {
/* 获取 IP 列表及其令牌 */
$ips = $m->get('ip_block', null, $cas);
/* 如果列表尚不存在,则创建它并进行
原子添加,如果其他人已经添加了它,则该添加将失败 */
if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
$ips = array($_SERVER['REMOTE_ADDR']);
$m->add('ip_block', $ips);
/* 否则,将 IP 添加到列表中,并通过比较和交换进行存储
使用令牌,如果其他人更新了列表,则该操作将失败 */
} else {
$ips[] = $_SERVER['REMOTE_ADDR'];
$m->cas($cas, 'ip_block', $ips);
}
} while (
$m->getResultCode() != Memcached::RES_SUCCESS);

?>

参见

添加注释

用户贡献的注释 4 个注释

abodera at gmail dot com
14 年前
注意!

使用二进制协议时,cas() 后的预期结果为 21 (Memcached::RES_END)。

例如,要使上面的示例 #1 与二进制协议一起使用,请使用以下内容
<?php
$m
= new Memcached();
$m->addServer('localhost', 11211);
$m->setOption(Memcached::OPT_BINARY_PROTOCOL,true)

// [...]

} else {
$ips[] = $_SERVER['REMOTE_ADDR'];
$m->cas($cas, 'ip_block', $ips);
}
} while (
$m->getResultCode() != Memcached::RES_END);
?>
sparcbr at gmail dot com
7 年前
不要使用类似以下内容的 while 循环检查命令是否成功


$memCached->getResultCode() != Memcached::RES_SUCCESS

Memcached::RES_SERVER_ERROR 或类似的东西,您的脚本将永远循环
Haravikk
6 年前
我不确定这在 Memcached 模块的新版本(v3.0 及更高版本)中是否仍然适用,但在与 PHP 5.6 一起提供的版本中,在启用 OPT_BINARY_PROTOCOL 时使用此方法的返回值和结果代码完全没有用。

成功设置值可能会返回 true,结果代码为 RES_END,但也可能会返回 true,结果代码为 RES_SUCCESS。

但是,*不成功*设置值同样似乎返回 true 和 RES_SUCCESS,实际上使此函数的返回值在启用二进制协议时变得毫无用处,因为它无法区分成功与失败。

如果您需要依赖此方法的返回值,我强烈建议在 PHP 5.6 中禁用二进制协议,因为在当前状态下,常见的 memcached 模块对于 CAS 使用来说太坏了。

希望其他人可以权衡这在较新版本中是否仍然存在问题。
php at sergentet dot fr
7 年前
为了防止在任何 Memcached 错误上出现永久循环,您可以添加一个简单的计数器

$security_count = 0;

do {
//[]....
$security_loop++
if ($security_loop > 10) {
break; //( 或在函数中返回“您的返回值”)
}
} while ($m->getResultCode() != Memcached::RES_SUCCESS);
To Top