2024 年 PHP Conference Japan

Memcached::cas

(PECL memcached >= 0.1.0)

Memcached::cas比較並交換項目

說明

public Memcached::cas(
    字串|整數|浮點數 $cas_token,
    字串 $key,
    混合 $value,
    整數 $expiration = 0
): 布林值

Memcached::cas() 執行「檢查並設定」操作,只有當此項目自上次被此客戶端擷取後沒有其他客戶端更新它時,該項目才會被儲存。檢查是透過 cas_token 參數完成的,該參數是由 memcache 指派給現有項目的唯一 64 位元值。關於如何取得此 token,請參閱 Memcached::get*() 方法的說明文件。請注意,由於 PHP 整數空間的限制,此 token 以浮點數表示。

參數

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 列表及其 token */
$ips = $m->get('ip_block', null, $cas);
/* 如果列表尚不存在,則建立它並執行
一個原子新增操作,如果其他人已經新增它,則會失敗 */
if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
$ips = array($_SERVER['REMOTE_ADDR']);
$m->add('ip_block', $ips);
/* 否則,將 IP 新增到列表並透過使用 token 的比較和交換來儲存
如果其他人更新了列表,則會失敗 */
} 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
8 年前
不要在 while 迴圈中使用類似以下程式碼檢查指令是否成功


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

Memcached::RES_SERVER_ERROR 或任何類似程式碼,否則您的腳本將會無限迴圈
Haravikk
7 年前
我不確定這在新版 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; //( 或是在函式中 return "您的回傳值" )
}
} while ($m->getResultCode() != Memcached::RES_SUCCESS);
To Top