постоянство — увеличение переменной между запросами PHP

Я пишу PHP-скрипт, который по запросу сделает вызов службы SOAP с различными параметрами, некоторые из которых взяты из запроса.

Однако конкретная служба SOAP, которую я использую, требует, чтобы каждый запрос содержал уникальный идентификатор, который в этом случае должен увеличиваться для каждого запроса. Оно не должно основываться на времени и должно быть уникальным для каждого запроса, однако не имеет значения, пропускаются ли значения.

Использование базы данных MySQL для хранения одного значения кажется чрезмерным излишним. Я думал о сохранении и загрузке его в файл, но возникает проблема условий гонки.

У меня есть полный доступ к серверу, который будет чем-то вроде Linux, посвященным этой задаче.

Есть ли простой способ, которым это может быть достигнуто?

2

Решение

Перед любым новым запросом получить инкрементное значение с использованием PHP time() функция, так как время будет уникальным для каждого запроса.

 $increment_id = time();
-1

Другие решения

Если ваше приложение — один сервер, вы можете попытаться сохранить инкрементный идентификатор в APC, используя:

$key = 'soap_service_name';
if (!apc_exists($key)) {
apc_store($key, 0);
}
$id = apc_inc($key);

Вам нужно проверить, существует ли ключ в кеше APC и установить 0, иначе apc_inc не удается и возвращается false

Если у вас есть многосерверное приложение, вы можете сохранить инкрементный идентификатор в Memcache / Redis (для этого нужно запустить дополнительный сервис):

$key = 'soap_service_name';
$memcache = memcache_connect('memcache_host', 11211);
if (!empty(memcache_exists($memcache, $key))) {
memcache_set($memcache, 0);
}
$id = memcache_increment($memcache, $key);

Та же ситуация, что и у APC, если вы звоните memcache_increment он потерпит неудачу, если ключ еще не существует.

Если этот инкрементный идентификатор должен храниться постоянно, Redis будет более полезным, потому что он имеет запись на диск всех данных. Это вроде Memcache с записью на диск.

-1

Вот как я добился этого в конце. После рассмотрения различных вариантов базы данных и различные варианты кэширования казались немного излишними. Кроме того, кажется, что кеширование, куки и сессии являются относительно временными, тогда как я действительно искал энергонезависимое решение.

Это то, что я придумал — простое решение для блокировки файлов. Я не осознавал, что PHP может справиться с блокировками файлов, но, обнаружив это, кажется, что это лучший способ.

Этот пример получает эксклюзивную блокировку файла перед чтением и обновлением значения. Если оно достигает максимального значения int, оно сбрасывается. Затем он ждет 5 секунд. Если скрипт вызывается несколько раз подряд, обратите внимание, что каждый запрос будет ожидать снятия блокировки с предыдущей, прежде чем продолжить.

Что приятно, так как это PHP, несуществующий файл, недопустимое содержимое и т. Д., То просто значение по умолчанию обнуляется.

<?php

$f = fopen('sequence_num.txt', 'r+');

echo "Acquiring lock<br />\n";
flock($f, LOCK_EX);

echo "Lock acquired, updating value<br />\n";
$num = intval(fread($f, strlen(PHP_INT_MAX)));
echo "Old val = " . $num;
if ($num >= PHP_INT_MAX) {
$num = 0;
} else {
$num++;
}
echo " New val = " . $num;
echo "<br />Waiting 5 seconds<br />\n";
rewind($f);
ftruncate($f, 0);
fwrite($f, $num);
sleep(5);

echo "Releasing lock<br />\n";
flock($f, LOCK_UN);
fclose($f);
-1

Если вы счастливы использовать float как уникальное значение, используйте:

$unique_id = microtime(true);

Если вы хотите просто увеличить, вы можете сделать это, используя сеанс var:

/**
* Get session increment.
*
* @param string $id
* @param int $default
* @return int
*/
function get_increment($id, $default = 0)
{
if (array_key_exists($id, $_SESSION)) $_SESSION[$id] += 1;

else $_SESSION[$id] = $default;

return $_SESSION[$id];
}

var_dump(get_increment('unique_id'));
-1
По вопросам рекламы [email protected]