PHP 8.5.0 Alpha 2 available for testing

Memcached::cas

(PECL memcached >= 0.1.0)

Memcached::casComparar y cambiar un elemento

Descripción

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

Memcached::cas() realiza una operación de "check and set" (literalmente, verificar y asignar), de manera que el elemento solo se almacena si ningún otro cliente lo ha actualizado desde que fue leído por el cliente actual. La verificación se realiza mediante el argumento cas_token que es un valor único de 64 bits, asignado al elemento por memcached. Consulte la documentación de Memcached::get*() para saber cómo obtener este valor. Tenga en cuenta que este valor se representa como un número flotante, debido a limitaciones en el espacio de enteros de PHP.

Parámetros

cas_token

Valor único asociado a un elemento existente. Generado por memcached.

key

The key under which to store the value.

value

The value to store.

expiration

The expiration time, defaults to 0. See Expiration Times for more info.

Valores devueltos

Esta función retorna true en caso de éxito o false si ocurre un error. El método Memcached::getResultCode() va devolver la constante Memcached::RES_DATA_EXISTS si el elemento que se intenta almacenar ha sido modificado desde la última lectura.

Ejemplos

Ejemplo #1 Ejemplo con Memcached::cas()

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

do {
/* Lee una IP y su CAS */
$ips = $m->get('ip_block', null, $cas);
/* Si la IP no existe aún, se crea y se realiza
un añadido atómico que fallará si la IP ya ha sido añadida */
if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
$ips = array($_SERVER['REMOTE_ADDR']);
$m->add('ip_block', $ips);
/* De lo contrario, se añade la IP a la lista, y se almacena con la operación
compare-and-swap y el token, que fallará si la lista ha sido actualizada */
} else {
$ips[] = $_SERVER['REMOTE_ADDR'];
$m->cas($cas, 'ip_block', $ips);
}
} while (
$m->getResultCode() != Memcached::RES_SUCCESS);

?>

Ver también

add a note

User Contributed Notes 4 notes

up
2
abodera at gmail dot com
15 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
8 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
7 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
8 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