MutantJohn Posted December 18, 2014 Share Posted December 18, 2014 Okay, so I'm kind of a PHP noob. But out of context, for this site that I'm designing, it's easiest if I make a directory in the temporary folder PHP uses. In my case, /tmp/ because I am on Linux. I want to use rand() to generate a random name for the page. But I then realized something, rand() could produce duplicates. How do I prevent PHP from trying to make the same directory at the same time? I know there are functions that will check if a file exists but I'm assuming it'll fail if that directory is currently being created, right? How do I assure thread safety? I willing to change my idea and not use rand(). Is there a way to get a unique key for each anonymous user on my site? Quote Link to comment https://forums.phpfreaks.com/topic/293170-unique-rand-directory-names-in-temp-folder/ Share on other sites More sharing options...
Jacques1 Posted December 18, 2014 Share Posted December 18, 2014 (edited) What you need to do is use a good random number generator. The rand() function is indeed poor and may produce duplicate results. But if you use the generator of your operating system, you'll get high-quality output and don't have to worry about any collisions. There are several different interfaces: If you have the Mcrypt extension, use mcrypt_create_iv() If you have the OpenSSL extension, use openssl_random_pseudo_bytes() If you have neither, you need to use the low-level API of your operating system. On Unix, there's the /dev/(u)random device. On Windows, it's a bit more complicated. 16 random bytes are enough to make the risk of collision neglectable (so no need for any checks). You then have to encode the raw bytes as hex digits or whatever you like best. For example: <?php $rand_bytes = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); $rand_hex = bin2hex($rand_bytes); echo $rand_hex; A lot of people will tell you that you should use things like mt_rand() or uniqid(). Don't. While those functions are slightly better than rand(), they're still poor compared to a proper generator like /dev/urandom. Edited December 18, 2014 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/293170-unique-rand-directory-names-in-temp-folder/#findComment-1500015 Share on other sites More sharing options...
MutantJohn Posted December 18, 2014 Author Share Posted December 18, 2014 Hey, that's a much better idea. I also read up on flock() but I couldn't get it to work. Just using PHP's native rand() function, I was planning on doing something like this : $outdir = "/tmp/"; $fp = fopen("/tmp", "w+"); // this works if (is_readable("/tmp")) echo "Can read directory.<br />\n"; // this works if (is_writable("/tmp")) echo "Can write directory.<br />\n"; // this always returns false if (flock($fp, LOCK_EX)) { // initial hash $dir_hash = rand(); // if the subdirectory/file exists, loop while (file_exists("/tmp/".$dir_hash)) { $dir_hash = rand(); } // append random number $outdir .= $dir_hash; // release lock flock($fp, LOCK_UN); } else echo "Was unable to lock directory <br />\n"; fclose($fp); echo $outdir."<br />\n"; Quote Link to comment https://forums.phpfreaks.com/topic/293170-unique-rand-directory-names-in-temp-folder/#findComment-1500017 Share on other sites More sharing options...
Jacques1 Posted December 18, 2014 Share Posted December 18, 2014 This makes no sense. I'm not sure if it's even possible to get an exclusive lock on a directory (Google suggests otherwise), but in any case, you're missing two things: The /tmp folder is used by lots and lots of processes, not just your PHP application. Making them all wait until you've created your user directories is a terrible idea. Locks obtained through flock() are only advisory, which means other applications are free to ignore them and overwrite your folders nonetheless. So the idea doesn't even work out. Like I said, proper randomness will make all checks and while loops unnecessary. But even if you're super-paranoid and want to rule out any chance of a collision, you still wouldn't do those checks. Simply call mkdir() and see if it failed. It does not overwrite existing folders but will throw an error instead. Quote Link to comment https://forums.phpfreaks.com/topic/293170-unique-rand-directory-names-in-temp-folder/#findComment-1500028 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.