1
\$\begingroup\$

How can I improve this code? I wanted to know if there's a possibility to remove the for loop, and UPDATE a different uniqueID for each ID in my database.

<?php
 $reponse = $bdd->prepare("SELECT MAX(ID) FROM tuto WHERE title=''");
 $reponse->execute();
 $IDnow = $reponse->fetch(PDO::FETCH_ASSOC);
 $IDnow = $IDnow['MAX(ID)'];
 for ($i=2 ; $i <= $IDnow ; $i++){
 $reponse = $bdd->prepare("UPDATE tuto SET uniqueID=:uniqueID WHERE uniqueID='' AND title='' AND ID=:i");
 $uniqueID = $donnees['uniqueID'];
 $int = rand(0,51);
 $a_z = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 $uniqueID = time().$a_z[$int];
 $reponse->execute([':uniqueID' => $uniqueID, 'i' => $i]);
 }
?>
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 14, 2016 at 11:45
\$\endgroup\$
2
  • \$\begingroup\$ This can be done in one SQL statement. Check out RAND() \$\endgroup\$ Commented Jan 14, 2016 at 11:40
  • \$\begingroup\$ what sql dbms is it for? each vendor has a different approach, for example MySQL stackoverflow.com/questions/14798640/creating-a-rhttp://… MSsql stackoverflow.com/questions/1045138/… Oracle \$\endgroup\$ Commented Jan 14, 2016 at 12:21

2 Answers 2

1
\$\begingroup\$

Finally, I used RAND(), for generate an "UniqueID", and we can add some letters after or else :

Thanks to NerdyDev and Bart Friederichs for solutions.

<?php
$reponse = $bdd->prepare("UPDATE tuto SET uniqueID=ROUND(RAND() * :tp) WHERE uniqueID='' AND title=''");
$uniqueID = $donnees['uniqueID'];
$tp = time();
$reponse->execute([':tp' => $tp]);
?>
answered Jan 14, 2016 at 12:48
\$\endgroup\$
5
  • \$\begingroup\$ RAND() generates a float in [0, 1). This means it is incredibly likely to generate collisions once you're dealing with a non-small number of rows. Think about it this way: a float is 32 bits. That means you have around 4 billion unique values, but RAND() only uses from 0 to 1 (though there is actually a higher concentration of float values around 0 than far away from 0 -- but it's still relatively small). \$\endgroup\$ Commented Jan 16, 2016 at 4:00
  • \$\begingroup\$ In this example, :tp is the time, so RAND() * time. We can generates a lot of values, and we can add letters, etc... \$\endgroup\$ Commented Jan 16, 2016 at 8:02
  • \$\begingroup\$ I'll try to post an answer explaining why this is a flawed approach to generate collision-resistant IDs tomorrow, but for the time being, I've slapped together a simulation in C++ here. If you go to "Edit" then click "Ideone It" you can run it a couple of times. I've yet to see it take more than 10,000 ID generations to hit a collision. If these IDs just need to be likely-unique (~ 0.01% chance of collision), then this approach will work, but if you need an almost unimaginable chance of collision, then this is likely to cause you a lot of pain. \$\endgroup\$ Commented Jan 16, 2016 at 9:05
  • \$\begingroup\$ (It might be worth noting that the above simulation makes a few assumptions about MySQL's RAND(). Primarily, the MySQL manual does not specify whether RAND returns a 32 or 64 bit float, so I have assumed 32 bit. Also, I have assumed RAND is internally using Mersenne Twister and very rarely reseeding (two things I consider fair assumptions)). \$\endgroup\$ Commented Jan 16, 2016 at 9:08
  • \$\begingroup\$ Yes, I agree with you, but the collision is not important for a news UID, and we can put a condition to check If there are some collisions and regenerates by using RAND(). \$\endgroup\$ Commented Jan 16, 2016 at 9:31
0
\$\begingroup\$

using foreach() loop will resolve your question.

<?php
$reponse = $bdd->prepare("SELECT MAX(ID) FROM tuto WHERE title=''");
$reponse->execute();
$IDnow = $reponse->fetch(PDO::FETCH_ASSOC);
$IDnow1 = $IDnow['MAX(ID)'];
foreach ($IDnow1 as $IDnow){
 $reponse = $bdd->prepare("UPDATE tuto SET uniqueID=:uniqueID WHERE uniqueID='' AND title='' AND ID=:i");
 $uniqueID = $donnees['uniqueID'];
 $int = rand(0,51);
 $a_z = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 $uniqueID = time().$a_z[$int];
 $reponse->execute([':uniqueID' => $uniqueID, 'i' => $IDnow]);
 }
?>

let me know if still any issue stands with your question. Good Luck!

answered Jan 14, 2016 at 11:43
\$\endgroup\$
2
  • \$\begingroup\$ Not working, "Invalid argument", but I'll try foreach. \$\endgroup\$ Commented Jan 14, 2016 at 12:02
  • \$\begingroup\$ yes the foreach will resolve your problem for sure. and sorry i've might have not completed the code properly. \$\endgroup\$ Commented Jan 14, 2016 at 12:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.