Build a unique slug

Hi,
I need a method
to build a slug (it should be unique) to insert in the Db
I ended up with this code:


public function buildSlug($value)
    {
      $slug = Zend_Filter::filterStatic($value, 'Slug');
      if(null === $this->getBySlug($slug)){
        return $slug;
      }
      $i = 1; 
      while (null !== $this->getBySlug($slug.'-'.$i)) { 
        $i++; 
      }
      return $slug.'-'.$i;
    }

I’m wondering if there is a better way ?

Bye

http://php.net/manual/en/function.time.php

Have you tried using the PHP time() function plus rand()?

yep but the top dog want from 1 to n

:smiley:

Using rand is a worse way imho

Instead of inserting a slug - how about creating a unique index and retrieving the value using mysql_insert_id()

or use hash(…), md5(…) or sh1(…). Search for the $result and if it is unique then insert into yor database otherwise try again?

.

If all you need is a unique field, and don’t care if it’s numeric or not, then use an AUTO-INCREMENT MySQL field.

If you don’t want it to be numeric, but don’t care for security much (people can guess it), use MD5(AUTO-INCREMENT MySQL field).

If you care a bit about people not guessing it, use MD5(‘AUTO-INCREMENT MySQL field’. ‘my special key’ . time())

If you want some text that people can “read”, you can do this:
Make your foo field unique.
generate your text, something like this:


# try 10 times
$i = 0;
while (!mysql_query("INSERT INTO table SET foo = '".getPass()."'") && $i<10) {
	$i++;
}
# generate a readable text
function getPass($length = 6) {
	$conso=array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","v","w","x","y","z");
	$vocal=array("a","e","i","o","u");
	$password="";
	srand ((double)microtime()*1000000);
	$max = ceil($length/2);
	for($i=1; $i<=$max; $i++) {
		$password.=$conso[rand(0,19)];
		$password.=$vocal[rand(0,4)];
	}
	return $password;
}

If you care about performance, you will make foo an index, generate a few strings, then


SELECT foo FROM table WHERE foo IN ('.join(',',$optionsArray).');

See what was found, and insert something it was not found. (do this in a loop)

There are many better ways to do this, but creating them 1 by 1 and doing selects in loops is not a good idea.