uniqueidentifier — PHP: лучший способ создать уникальный числовой идентификатор

Мне нужно генерировать уникальные числовой Я бы.

  • Я мог бы использовать uniqid, но он генерирует буквенно-цифровое значение.

  • И снова я мог бы использовать время, но нет никаких гарантий, что это
    будет уникальным всегда.

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

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

4

Решение

Ничто не может гарантировать 100% уникальность.

Вам нужно знать уникальность сравнивая с чем тебе нужно.

И используйте любой алгоритм плюс проверьте каждое значение в списке всех используемых значений.

В мире программирования то, что вам нужно, называется pseudo random число. Так что это название на самом деле объясняет, что я имею в виду.

4

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

Системы баз данных используют эксклюзивную блокировку при создании чисел, таких как MySQL auto_increment который заботится о параллелизме и многих других запутанных деталях.

Вы должны подходить к проблеме, которая у вас есть, таким же образом — получить блокировку от процесса PHP, который обслуживает запрос, посмотреть текущее значение в некотором постоянном хранилище, увеличить его на 1, вернуть и снять блокировку.

Самый простой способ сделать это — использовать старый добрый файл и эксклюзивную блокировку.

Я проиллюстрирую с классом (который должен быть отлаженным, так как он не завершен):

class MyAutoIncrement
{
protected $fh = null;
protected $file_path = '';
protected $auto_increment_offset = 1;

public function __construct($file_path, $offset = 1)
{
$this->file_path = $file_path;
$this->auto_increment_offset = $offset;
}

public function autoincrement()
{
if($this->acquire())
{
$current = (int)fread($this->fh);

$next += $this->auto_increment_offset;

fwrite($this->fh, $next);

$this->release();

return $next;
}

return null;
}

public function acquire()
{
$handler = $this->getFileHandler();

return flock($handler, LOCK_EX);
}

public function release($close = false)
{
$handler = $this->getFileHandler();

return flock($handler, LOCK_UN);

if($close)
{
fclose($handler);
$this->fh = null;
}
}

protected function acquireLock($handler)
{
return flock($handler, LOCK_EX);
}

protected function getFileHandler()
{
if(is_null($this->fh))
{
$this->fh = fopen($this->file_path, 'c+');

if($this->fh === false)
{
throw new \Exception(sprintf("Unable to open the specified file: %s", $this->file_path));
}
}

return $this->fh;
}
}

Использование:

$ai = new MyAutoIncrement('/path/to/counter/file.txt');

try
{
$id = $ai->autoincrement();

if(!is_null($id))
{
// Voila, you got your number, do stuff
}
else
{
// We went wrong somewhere
}
}
catch(\Exception $e)
{
// Something went wrong
}
3

Как упоминалось ранее. Ничто не может гарантировать 100% уникальность.

Хотя это будет довольно уникально 🙂

$iUniqueNumber = crc32(uniqid());

Увидеть
uniqid а также crc32 полином строки.

1

Вы можете использовать комбинацию время() а также getmypid () чтобы получить то, что вам нужно — числовой уникальный идентификатор. Вы можете запустить несколько процессов php в одно и то же время, но они никогда не будут иметь одинаковый идентификатор процесса в данный момент времени (если только счетчик серверных процессов не перекрывается менее чем за секунду, что практически невозможно, если kernel.pid_max установлен правильно).

<?
function getUniqueID() {
return time() . '.' . getmypid();
}
?>

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

1

Вы можете сделать свое собственное значение приращения, чтобы гарантировать 100% уникальность без использования тяжелых алгоритмов:

Уникальный идентификатор сессии:

session_start();

$_SESSION['increment'] = 5;//i fix 5 but you need to get it in bdd,xml,...

function get_new_id(){
$_SESSION['increment']++;
//store new value of increment
return $_SESSION['increment'];
}

$my_unique_id = get_new_id();
echo $my_unique_id;

Глобальный уникальный идентификатор (не используйте это!):

function get_new_id(){
$increment = file_get_contents('increment.txt');
$increment++;
file_put_contents('increment.txt', $increment);
return $increment;
}

$my_unique_id = get_new_id();
echo $my_unique_id;
0

Вы говорили о времени, а как насчет микропоры?

Даже если вы создадите два числа подряд, вы получите другое значение. Конечно, вам нужно немного поиграть, чтобы сделать его уникальным целым числом, но оно должно помочь.

0
function getserial()
{
$fn='/where_you_want/serial.dat';
$fp = fopen($fn, "r+");
if (flock($fp, LOCK_EX)) { $serial=fgets($fp);$serial++; }
else
{ print('lock error, ABORT'); exit; }
$h=fopen($fn.'.tmp','w'); fwrite($h,$serial);fclose($h);
if (filesize($fn.'.tmp')>0)
{
system('rm -f '.$fn.'.tmp');
fseek ($fp, 0);
fwrite($fp,$serial);
}
flock($fp, LOCK_UN); fclose($fp); @chmod($fn,0777);
return $serial;
}

В этом примере вы получите уникальный серийный номер, после чего вы можете быть уверены, что он существует только с одним экземпляром.
пожалуйста, обратите внимание, чтобы избежать повреждения данных, вы должны сначала создать свой файл и поставить номер первым.
(например, напишите 1 без ввода или что-нибудь еще)

это действительно простая функция, но она работает для меня уже более 10 лет …

0

Я предлагаю объединить ID процесса PHP с microtime (true), чтобы увеличить возможность иметь уникальное значение.

-1
По вопросам рекламы [email protected]