Home » Php » php – Make a post slug unique

php – Make a post slug unique

Posted by: admin July 12, 2020 Leave a comment

Questions:

I got few functions in placed which is not working as I wanted.

The slug is automicatlly created on the fly depend on the post title.

Example: If a post title is “test” then the slug will be “test”

My problem is that, what if theirs duplicate entry of post title “test” which means that the slug will be duplicated too. For that reason I have create 2 functions to handle this for me.

This function checks if the slug exist in the database

function slug_exist($x){
    global $db;
        $sql = "SELECT post_name FROM posts WHERE post_name=\"$x\"";
        $query = $db->select($sql);
            if($db->num_rows() > 0){
                return true;
    }
}

If the slug does exist in the database then am using this function to give the slug a unique name

    if(slug_exist($slug)){
        $rand = rand(10,50);
        $slug = $slug."-".$rand;
            return $slug;
    }

Well when the slug will get unique slug name it will be like Example: test-244

I want the slugs to be in numeric order and not in random order.

**Example:**

Post Title is "Test"
Slug is "test-1"

Post Title is "Test"
Slug is "test-2"

Post Title is "Test"
Slug is "test-3"

This is the only way I know how to explain in detail please let me know if you are not sure what am taking about. Thanks!

How to&Answers:

This is a very standard code, just you need a small loop:

$i = 1; $baseSlug = $slug;
while(slug_exist($slug)){
    $slug = $baseSlug . "-" . $i++;        
}

return $slug;

Answer:

<?php
$oSlug    = 'Test';
$slug     = $oSlug;
$count = 1;
while(slug_exist($slug)){
    $slug = $oSlug.'-'.$count++;
}
print 'The slug i got is: '.$slug;
?>

Answer:

I had been working on mine for a few hours before I stumbled upon this. This question assisted me a little but I ended up with something a bit different;

I had also created a function to check if a slug already exists;

function slugExist($slug){
    global $db;
    $query = $db->query("SELECT * FROM `blog-posts` WHERE `slug` = '".$slug."'");
    $results = $query->num_rows;
    if($results > 0){
        return true;
    }else{
        return false;
    }
}

For Posting a new Article or Post (depending on what you are doing) I have the following;

    $slug = furl($_POST['title']);

    $CheckSlug = $db->query("SELECT * FROM `blog-posts` WHERE `slug` LIKE '".$slug."%'");
    $numHits = $CheckSlug->num_rows;
    if($numHits > 0){
        $slug = $slug.'-'.$numHits;
    }

This is much easier on execution as there is no loop and it’s very clean. But what if you are editting an existing post? You want the slug to change if they change the title but you dont want it to change or increase/decrease the numeric suffix if the user doesn’t.

So using a few posts I ended up with this;

$slug = furl($_POST['title']);

if($slug != $oldSlug){                      // 1. If the slug of the new title is different to the old one, proceed to adding suffix
    $i = 1; $baseSlug = $slug;              // 2. Set counter and baseSlug vars.
    while(slugExist($slug)){                // 3. Start a loop to keep adding to the numeric value until an empty one is found
        $slug = $baseSlug . "-" . $i++;     // 4. Set the new slug variable to the base with a new number
        if($slug == $oldSlug){              // 5. If the slug with the added number matchs the existing slug, then we dont want to change it
            break;                          // 6. Break the loop to prevent additional numeric changes to the slug
        }
    }
}

I know this is a bit of an older question but I hope that this helps at least one other person in the future.

Answer:

If you have full access to your db and like store logic in db you can

  • add unique index to slug and catch exception on insert
  • add trigger on insert to do slug generation work for you