What is the correct way to generate UUID with PHP?

WBOY
Release: 2023-03-01 21:36:01
Original
2116 people have browsed it

After searching online, I found that they are generally similar to the following:

<code>        $chars = md5(uniqid(mt_rand(), true));
        $uuid  = substr($chars,0,8) . '-';
        $uuid .= substr($chars,8,4) . '-';
        $uuid .= substr($chars,12,4) . '-';
        $uuid .= substr($chars,16,4) . '-';
        $uuid .= substr($chars,20,12);
        return $prefix . $uuid;</code>
Copy after login
Copy after login
<code>            mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.随便数播种,4.2.0以后不需要了。
            $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根据当前时间(微秒计)生成唯一id.
            $hyphen = chr ( 45 );
            $uuid = '' . 
                substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 );
            return $uuid;</code>
Copy after login
Copy after login

After reading the description of UUID, why do I feel that the impact rate of these generation methods does not meet the standards?

Reply content:

After searching online, I found that they are generally similar to the following:

<code>        $chars = md5(uniqid(mt_rand(), true));
        $uuid  = substr($chars,0,8) . '-';
        $uuid .= substr($chars,8,4) . '-';
        $uuid .= substr($chars,12,4) . '-';
        $uuid .= substr($chars,16,4) . '-';
        $uuid .= substr($chars,20,12);
        return $prefix . $uuid;</code>
Copy after login
Copy after login
<code>            mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.随便数播种,4.2.0以后不需要了。
            $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根据当前时间(微秒计)生成唯一id.
            $hyphen = chr ( 45 );
            $uuid = '' . 
                substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 );
            return $uuid;</code>
Copy after login
Copy after login

After reading the description of UUID, why do I feel that the impact rate of these generation methods does not meet the standards?

At present, many so-called PHP methods for generating UUIDs use random numbers as the basis of their algorithms. Although it is difficult to have a chance of repetition in practice, it is obviously not feasible in theory.

MongoDb’s ObjectId is used as an example here. I personally feel that this generation method can be introduced into PHP.
ObjectId is mainly divided into four parts: timestamp, milliseconds, machine code, and auto-increment count.

There is no need to go into details about the first two, PHP can be obtained, the focus is on the latter two.

Machine code is mainly used to avoid generating the same UUID between different hosts.
The current main method of generating machine code is hash calculation based on hardware information, and this method is not suitable for PHP.
Mainly because of two points, one is that PHP cannot directly obtain hardware information (it needs to be extended or executed local commands, etc.), and the other is that data cannot be shared between PHP requests, so each request has to pull the machine code. The performance impact is huge.
There is a very simple way to solve this problem, which is to first calculate the machine code on different machines, then directly write it into the configuration file, and then read it directly during PHP processing.

Auto-incrementing count is mainly used to avoid generating the same UUID in concurrent processing.
For auto-increment, PHP cannot directly implement auto-increment counting because it cannot share data between requests.
To solve this problem, we can introduce two extensions of PHP, namely Semaphore and Shared Memory, both of which are integrated in the PHP source code and can be opened through --enable-sysvsem and --enable-sysvshm. We only need to place the auto-increment number in the shared memory and then restrict access through the semaphore to achieve the purpose of concurrent requests to share the auto-increment technology. Of course, self-increment can also be achieved through other tools.

The Linux kernel provides a UUID generation interface:
cat /proc/sys/kernel/random/uuid
Everything on Linux is a file. No matter what program, you can get a UUID by reading the file.

Generate a unique value by yourself:

<code>php best.php
<?php
echo uniqid(mt_rand().'_', true)."\n";
echo uniqid(mt_rand().'_', true)."\n";
//代码前后两次调用输出都不一样:
405797689_58295933a5de69.42485678
748054035_58295933a5e072.26553654
//如果运行时再加上远程用户地址/端口/进程PID的话,唯一性应该都已经够用了.
echo uniqid($_SERVER['REMOTE_ADDR'].'_'.$_SERVER['REMOTE_PORT'].'_'.getmypid().'_'.mt_rand().'_', true)."\n";
echo uniqid($_SERVER['REMOTE_ADDR'].'_'.$_SERVER['REMOTE_PORT'].'_'.getmypid().'_'.mt_rand().'_', true)."\n";</code>
Copy after login

In addition, it seems that using openssl_random_pseudo_bytes can also generate a good random string:

<code>echo base64_encode(openssl_random_pseudo_bytes(32));</code>
Copy after login
Related labels:
php
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template