Bei einer Online-Suche habe ich festgestellt, dass sie im Allgemeinen den folgenden ähneln:
<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>
<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>
Warum haben Sie nach dem Lesen der UUID-Beschreibung das Gefühl, dass die Auswirkungsrate dieser Generierungsmethoden nicht den Standards entspricht?
Bei einer Online-Suche habe ich festgestellt, dass sie im Allgemeinen den folgenden ähneln:
<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>
<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>
Warum haben Sie nach dem Lesen der UUID-Beschreibung das Gefühl, dass die Auswirkungsrate dieser Generierungsmethoden nicht den Standards entspricht?
Viele der sogenannten PHP-Methoden zur Generierung von UUIDs verwenden derzeit Zufallszahlen als Grundlage ihrer Algorithmen. Obwohl dies in der Praxis wahrscheinlich nicht der Fall sein wird, ist es theoretisch offensichtlich nicht realisierbar.
Hier verwenden wir die ObjectId von MongoDb als Beispiel. Ich persönlich bin der Meinung, dass diese Generierungsmethode in PHP eingeführt werden kann.
ObjectId ist hauptsächlich in vier Teile unterteilt: Zeitstempel, Millisekunden, Maschinencode und Anzahl der automatischen Inkremente.
Auf die ersten beiden muss nicht näher eingegangen werden. Der Schwerpunkt liegt auf den letzten beiden.
Maschinencode wird hauptsächlich verwendet, um die Generierung derselben UUID zwischen verschiedenen Hosts zu vermeiden.
Die derzeitige Hauptmethode zum Generieren von Maschinencode ist die Hash-Berechnung basierend auf Hardwareinformationen. Diese Methode ist nicht für PHP geeignet.
Hauptsächlich aus zwei Gründen: Zum einen kann PHP keine Hardwareinformationen direkt abrufen (muss lokale Befehle erweitern oder ausführen usw.), und zum anderen kann PHP keine Daten zwischen Anfragen teilen, sodass jede Anfrage die Daten abrufen muss Maschinencode, der einen großen Einfluss auf die Leistung hat.
Es gibt eine sehr einfache Möglichkeit, dieses Problem zu lösen: Berechnen Sie zunächst den Maschinencode auf verschiedenen Maschinen, schreiben Sie ihn dann direkt in die Konfigurationsdatei und lesen Sie ihn dann direkt während der PHP-Verarbeitung.
Die automatische Inkrementierung wird hauptsächlich verwendet, um zu vermeiden, dass bei der gleichzeitigen Verarbeitung dieselbe UUID generiert wird.
Für die automatische Inkrementierung kann PHP die automatische Inkrementzählung nicht direkt implementieren, da es keine Daten zwischen Anforderungen teilen kann.
Um dieses Problem zu lösen, können wir zwei Erweiterungen von PHP einführen, nämlich Semaphore und Shared Memory, die beide in den PHP-Quellcode integriert sind und über --enable-sysvsem und --enable-sysvshm geöffnet werden können. Wir müssen nur die Auto-Inkrement-Nummer im gemeinsam genutzten Speicher platzieren und dann den Zugriff über die Semaphore einschränken, um den Zweck gleichzeitiger Anforderungen zur gemeinsamen Nutzung der Auto-Inkrement-Technologie zu erreichen. Selbstverständlich kann die Selbstinkrementierung auch durch andere Tools erreicht werden.
Der Linux-Kernel bietet eine UUID-Generierungsschnittstelle: cat /proc/sys/kernel/random/uuid
Alles unter Linux ist eine Datei, egal welches Programm, Sie können eine UUID erhalten, indem Sie die Datei lesen.
Generieren Sie selbst einen einzigartigen Wert:
<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>
Darüber hinaus scheint die Verwendung von openssl_random_pseudo_bytes
auch eine gute Zufallszeichenfolge generieren zu können:
<code>echo base64_encode(openssl_random_pseudo_bytes(32));</code>