Question: I have a function for creating unique slug for a page title. It checks if the slug is available in the pages table then creates a unique slug by adding a '-int' accordingly. The function works fine for the first three entries eg for 'test slug' entered three time will create 'test-slug-1', 'test-slug-2' and 'test-slug-3'. Then after that I get an error "Fatal error: Maximum execution time of 30 seconds exceeded" for the fourth entry. There should be some problem with the logic, can anyone help me find it please.Below is the code:

```
function createSlug($title, $table_name, $field_name) {

global $db_connect;

$slug = preg_replace("/-$/","",preg_replace('/[^a-z0-9]+/i', "-", strtolower($title)));

$counter = 1;

do{

  $query = "SELECT * FROM $table_name WHERE  $field_name  = '".$slug."'";
  $result = mysqli_query($db_connect, $query) or die(mysqli_error($db_connect));

  if(mysqli_num_rows($result) > 0){
      $count = strrchr($slug , "-"); 
      $count = str_replace("-", "", $count);
      if($count > 0){

          $length = count($count) + 1;
          $newSlug = str_replace(strrchr($slug , "-"), '',$slug);
          $slug = $newSlug.'-'.$length;

          $count++;

      }else{
          $slug = $slug.'-'.$counter;
      }  

  }

  $counter++; 
  $row = mysqli_fetch_assoc($result);

}while(mysqli_num_rows($result) > 0);

return $slug;

```

}

Answer: 
You can just select slug with the biggest number and increase it with 1:

```
$query = "SELECT $field_name FROM $table_name WHERE  $field_name LIKE '".$slug."-[0-9]*' ORDER BY $field_name DESC LIMIT 1";

```

`[0-9]*` in query means any count of numbers.

This query will select row with `$slug` at start and the bigest number.

After that you can parse result get number and increase it.

In this case you will have only one query and lot of unused performance.

**UPDATE**

This will not work, because `slug-8` will be "bigger" than `slug-11`. But no idea how to fix it. maybe `ORDER BY`id`DESC` ?

**UPDATE 2**

Query can be ordered by length too and it will work right. Thanks to Jack:

```
$query = "SELECT $field_name FROM $table_name WHERE  $field_name LIKE '".$slug."-[0-9]*' ORDER BY LENGTH($field_name), $field_name DESC LIMIT 1";

```

**UPDATE 3**

Also added check for original slug. Thanks to Hailwood.

```
$query = "SELECT $field_name FROM $table_name WHERE $field_name = '".$slug."' OR $field_name LIKE '".$slug."-[0-9]*' ORDER BY LENGTH($field_name), $field_name DESC LIMIT 1";

```
I wasn't fully satisfied with the answers, so I came up with a slightly different approach.

```
(SELECT CONCAT({$slug}, '-', counter) FROM (
  SELECT (@row_number:=@row_number + 1) AS counter, ev.*
  FROM (
    SELECT REPLACE(slug, {$slug}-, '') AS remainder
    FROM products, (SELECT @row_number:=0) AS t
    WHERE slug LIKE '{$slug}%'
  ) ev
  ORDER BY LENGTH(remainder), remainder
) sr
WHERE counter <> remainder)
LIMIT 1

```

What this basically does, it checks all the existing values in the DB that are similar to the new slug, and matches it against the row number to check for gaps, and if none is found, it uses the maximum number that's generated by the first identical slug that gets pushed to the end (note: we replace `slug-` and not `slug`)