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, который представляет собой 64-битное значение присвоенное существующей записи сервером memcache. Обратитесь к документации метода Memcached::get*(), который используется для получения этого токена. Обратите внимание, что токен представлен в виде числа с плавающей точкой из-за ограничений диапазона значений целочисленного типа в PHP.

Список параметров

cas_token

Уникальное значение, связанное с существующей записью. Генерируется сервером memcache.

key

Ключ, под которым сохраняется значение.

value

Сохраняемое значение.

expiration

Время хранения объекта, по умолчанию равно 0. Для более подробной информации смотрите Время хранения объекта.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Метод Memcached::getResultCode() возвращает Memcached::RES_DATA_EXISTS если запись которую вы пытаетесь сохранить была изменена с момента последнего обращения.

Примеры

Пример #1 Пример использования Memcached::cas()

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

do {
/* fetch IP list and its token */
$ips = $m->get('ip_block', null, $cas);
/* if list doesn't exist yet, create it and do
an atomic add which will fail if someone else already added it */
if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
$ips = array($_SERVER['REMOTE_ADDR']);
$m->add('ip_block', $ips);
/* otherwise, add IP to the list and store via compare-and-swap
with the token, which will fail if someone else updated the list */
} else {
$ips[] = $_SERVER['REMOTE_ADDR'];
$m->cas($cas, 'ip_block', $ips);
}
} while (
$m->getResultCode() != Memcached::RES_SUCCESS);

?>

Смотрите также

  • Memcached::casByKey() - Сравнивает и устанавливает значение для записи на конкретном сервере

add a note add a note

User Contributed Notes 4 notes

up
3
abodera at gmail dot com
14 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
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
7 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);
up
1
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
To Top