Memcached::cas

(PECL memcached >= 0.1.0)

Memcached::casCompara e troca um item

Descrição

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

Memcached::cas() realiza uma operação de "check and set", de forma que o item será armazenado apenas se nenhum outro cliente o tiver atualizado desde a última vez que foi buscado por este cliente. A verificação é feita por meio do parâmetro cas_token, que é um valor exclusivo de 64 bits atribuído ao item existente pelo memcache. Consulte a documentação dos métodos Memcached::get*() para saber como obter esse token. Observe que o token é representado como um float devido às limitações do espaço inteiro do PHP.

Parâmetros

cas_token

Valor exclusivo associado ao item existente. Gerado por memcache.

key

A chave sobre a qual guardar o valor.

value

O valor para guardar.

expiration

O tempo de expiração, padrão é 0. Veja Tempos de Expiração para maiores informações.

Valor Retornado

Retorna true em caso de sucesso ou false em caso de falha. O Memcached::getResultCode() retornará Memcached::RES_DATA_EXISTS se o item que você está tentando armazenar tiver sido modificado desde a última vez que você o buscou.

Exemplos

Exemplo #1 Memcached::cas() example

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

do {
/* busca lista de IP e seu token */
$ips = $m->get('ip_block', null, $cas);
/* se a lista ainda não existir, crie-a e faça
uma adição atômica que falhará se alguém já tiver adicionado i */
if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
$ips = array($_SERVER['REMOTE_ADDR']);
$m->add('ip_block', $ips);
/* caso contrário, adicione o IP à lista e armazene via comparação e troca
com o token, que falhará se outra pessoa atualizar a lista */
} else {
$ips[] = $_SERVER['REMOTE_ADDR'];
$m->cas($cas, 'ip_block', $ips);
}
} while (
$m->getResultCode() != Memcached::RES_SUCCESS);

?>

Veja Também

add a note

User Contributed Notes 4 notes

up
2
abodera at gmail dot com
12 years ago
Watch out!

When using binary protocol, the expected result after cas() is 21 (Memcached::RES_END).

For example, to make the above example #1 work with binary protocol, use the following:
<?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);
?>
up
2
sparcbr at gmail dot com
6 years ago
Do not check command success in a while loop with something like

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

Memcached::RES_SERVER_ERROR or anything like this and your script will loop forev
up
1
Haravikk
5 years ago
I'm not sure whether this remains true in the newer versions of the Memcached module (v3.0 onwards) but in the version shipped with PHP 5.6 the return value and result code when using this method with OPT_BINARY_PROTOCOL enabled are entirely useless.

Setting a value successful may return true, with a result code of RES_END, but it may also return true with a result code of RES_SUCCESS.

However, *unsuccessfully* setting a value likewise seems to return true and RES_SUCCESS, effectively rendering this function's return value useless with the binary protocol enabled as it is impossible to distinguish success from failure.

If you need to rely on the return value of this method then I strongly recommend disabling the binary protocol under PHP 5.6, as in its current state the common memcached module is too broken otherwise for CAS usage.

Hopefully someone else can weigh in on whether this is still broken in newer versions or not.
up
1
php at sergentet dot fr
5 years ago
To prevent a perpetual loop on any Memcached error, you can add a simple counter :

$security_count = 0;

do {
        //[]....
        $security_loop++
        if ($security_loop > 10) {
                break;     //( or return "your return value" on a function )
        }
} while ($m->getResultCode() != Memcached::RES_SUCCESS);
To Top