Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

toniperic's avatar

L5 Routing

This doesn't really have much to do with Laravel 5 routing but rather slugs. Seeing Jeffrey is using slugs in the forum links, what happens if there are two threads with the same slug?

As you may have noticed, there already exists a thread with this same name, which should result in the same slug I suppose. I am gonna submit this post/thread now and see what happens...

Edit: Oh, smart enough, it added -1 to the slug. Now... I am curious how would you implement this in your app?

0 likes
19 replies
RachidLaasri's avatar

You just check if a post exist in your database with the same slug, if yes get the count, and apped it +1 to the new post.

RachidLaasri's avatar

Only one, "select count(*) from posts where slug = new_slug", this query will return the count.

if it's 0, then just insert it with the given slug. if it's > 0 then add 1 to the result of the query to the slug.

1 like
RachidLaasri's avatar

@JarekTkaczyk i think like will return too many results, maybe using a function to trim the last "-1". or maybe using a foreach to check? for example it'll first check if the "l5-routing" is exist if yes, append -1 to it then check if "l5-routing-1" exist if yes, append "-2" to it. i think there will not be too many topics with the same slug, so two or 3 queries are fine.

1 like
toniperic's avatar

@RachidLaasri You could still do it with one query, regardless.

If the id field is auto-incrementing, then just do a like query, order by id in descending order and also limit to one result. If you get no results, you can insert slug as-is. If there are results, you get the last result and just make +1 to it.

JarekTkaczyk's avatar

@toniperic to be precise, simple like won't do:

| title              | slug               |
| L5 Routing         | l5-routing         |
| L5 Routing         | l5-routing-1       |
| L5 Routing issue   | l5-routing-issue   |
| L5 Routing problem | l5-routing-problem |

select count(*) from conversations where slug like 'l5-routing%'
// 4

// vs.
select count(*) from conversations where slug rlike '^l5-routing(-[0-9]+)?$'
// 2

thinking MySQL of course

2 likes
JeffreyWay's avatar
Level 59

Yeah, it's pretty simple to deal with the slug thing. You might try something like:


/** * Create a conversation slug. * * @param string $title * @return string */ public function makeSlugFromTitle($title) { $slug = Str::slug($title); $count = Conversation::whereRaw("slug RLIKE '^{$slug}(-[0-9]+)?$'")->count(); return $count ? "{$slug}-{$count}" : $slug; }
24 likes
cipsas's avatar

I try to use this function:

/**
 * Create a conversation slug.
 *
 * @param  string $title
 * @return string
 */
public function makeSlugFromTitle($title)
{
    $slug = Str::slug($title);

    $count = Conversation::whereRaw("slug RLIKE '^{$slug}(-[0-9]+)?$'")->count();

    return $count ? "{$slug}-{$count}" : $slug;
}

But I get error "Invalid argument: arguments: (too few)". I find out in ->whereRaw() question mark was interpreted as placeholder for sql, not as optional param in REGEXP. How to fix it?

pmall's avatar

You can store two slugs, the original slug and the unique slug. So one query, no regex :)

cipsas's avatar

@pmall it would be workaround. But this function should work if people share and accept.

Man's avatar

I am getting a 'Conversation' class not found error

cristo's avatar

How come nobody mentioned that the solution by Jeff is open to SQL injection; you're injecting the variable directly in the query... Instead, you need to pass it as the 2nd parameter. Check the docs https://laravel.com/api/master/Illuminate/Database/Query/Builder.html#method_whereRaw

Having said that, I was having problems with the ? placeholder, because the query builder was confusing the second ? in the regex. So I did the following:

if ($count = Product::where('slug', 'like', "$slug%")->count())
    $slug = str_finish($slug, "-$count");
1 like

Please or to participate in this conversation.